1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/download/database/download_db_conversions.h"
6
7 #include <utility>
8 #include "base/logging.h"
9 #include "base/pickle.h"
10
11 namespace download {
12
DownloadEntryFromProto(const download_pb::DownloadEntry & proto)13 DownloadEntry DownloadDBConversions::DownloadEntryFromProto(
14 const download_pb::DownloadEntry& proto) {
15 DownloadEntry entry;
16 entry.guid = proto.guid();
17 entry.request_origin = proto.request_origin();
18 entry.download_source = DownloadSourceFromProto(proto.download_source());
19 entry.ukm_download_id = proto.ukm_download_id();
20 entry.bytes_wasted = proto.bytes_wasted();
21 entry.fetch_error_body = proto.fetch_error_body();
22 for (const auto& header : proto.request_headers()) {
23 entry.request_headers.emplace_back(HttpRequestHeaderFromProto(header));
24 }
25 return entry;
26 }
27
DownloadEntryToProto(const DownloadEntry & entry)28 download_pb::DownloadEntry DownloadDBConversions::DownloadEntryToProto(
29 const DownloadEntry& entry) {
30 download_pb::DownloadEntry proto;
31 proto.set_guid(entry.guid);
32 proto.set_request_origin(entry.request_origin);
33 proto.set_download_source(DownloadSourceToProto(entry.download_source));
34 proto.set_ukm_download_id(entry.ukm_download_id);
35 proto.set_bytes_wasted(entry.bytes_wasted);
36 proto.set_fetch_error_body(entry.fetch_error_body);
37 for (const auto& header : entry.request_headers) {
38 auto* proto_header = proto.add_request_headers();
39 *proto_header = HttpRequestHeaderToProto(header);
40 }
41 return proto;
42 }
43
44 // static
DownloadSourceFromProto(download_pb::DownloadSource download_source)45 DownloadSource DownloadDBConversions::DownloadSourceFromProto(
46 download_pb::DownloadSource download_source) {
47 switch (download_source) {
48 case download_pb::DownloadSource::UNKNOWN:
49 return DownloadSource::UNKNOWN;
50 case download_pb::DownloadSource::NAVIGATION:
51 return DownloadSource::NAVIGATION;
52 case download_pb::DownloadSource::DRAG_AND_DROP:
53 return DownloadSource::DRAG_AND_DROP;
54 case download_pb::DownloadSource::FROM_RENDERER:
55 return DownloadSource::FROM_RENDERER;
56 case download_pb::DownloadSource::EXTENSION_API:
57 return DownloadSource::EXTENSION_API;
58 case download_pb::DownloadSource::EXTENSION_INSTALLER:
59 return DownloadSource::EXTENSION_INSTALLER;
60 case download_pb::DownloadSource::INTERNAL_API:
61 return DownloadSource::INTERNAL_API;
62 case download_pb::DownloadSource::WEB_CONTENTS_API:
63 return DownloadSource::WEB_CONTENTS_API;
64 case download_pb::DownloadSource::OFFLINE_PAGE:
65 return DownloadSource::OFFLINE_PAGE;
66 case download_pb::DownloadSource::CONTEXT_MENU:
67 return DownloadSource::CONTEXT_MENU;
68 case download_pb::DownloadSource::RETRY:
69 return DownloadSource::RETRY;
70 }
71 NOTREACHED();
72 return DownloadSource::UNKNOWN;
73 }
74
75 // static
DownloadSourceToProto(DownloadSource download_source)76 download_pb::DownloadSource DownloadDBConversions::DownloadSourceToProto(
77 DownloadSource download_source) {
78 switch (download_source) {
79 case DownloadSource::UNKNOWN:
80 return download_pb::DownloadSource::UNKNOWN;
81 case DownloadSource::NAVIGATION:
82 return download_pb::DownloadSource::NAVIGATION;
83 case DownloadSource::DRAG_AND_DROP:
84 return download_pb::DownloadSource::DRAG_AND_DROP;
85 case DownloadSource::FROM_RENDERER:
86 return download_pb::DownloadSource::FROM_RENDERER;
87 case DownloadSource::EXTENSION_API:
88 return download_pb::DownloadSource::EXTENSION_API;
89 case DownloadSource::EXTENSION_INSTALLER:
90 return download_pb::DownloadSource::EXTENSION_INSTALLER;
91 case DownloadSource::INTERNAL_API:
92 return download_pb::DownloadSource::INTERNAL_API;
93 case DownloadSource::WEB_CONTENTS_API:
94 return download_pb::DownloadSource::WEB_CONTENTS_API;
95 case DownloadSource::OFFLINE_PAGE:
96 return download_pb::DownloadSource::OFFLINE_PAGE;
97 case DownloadSource::CONTEXT_MENU:
98 return download_pb::DownloadSource::CONTEXT_MENU;
99 case DownloadSource::RETRY:
100 return download_pb::DownloadSource::RETRY;
101 }
102 NOTREACHED();
103 return download_pb::DownloadSource::UNKNOWN;
104 }
105
DownloadEntriesFromProto(const download_pb::DownloadEntries & proto)106 std::vector<DownloadEntry> DownloadDBConversions::DownloadEntriesFromProto(
107 const download_pb::DownloadEntries& proto) {
108 std::vector<DownloadEntry> entries;
109 for (int i = 0; i < proto.entries_size(); i++)
110 entries.push_back(DownloadEntryFromProto(proto.entries(i)));
111 return entries;
112 }
113
DownloadEntriesToProto(const std::vector<DownloadEntry> & entries)114 download_pb::DownloadEntries DownloadDBConversions::DownloadEntriesToProto(
115 const std::vector<DownloadEntry>& entries) {
116 download_pb::DownloadEntries proto;
117 for (size_t i = 0; i < entries.size(); i++) {
118 download_pb::DownloadEntry* proto_entry = proto.add_entries();
119 *proto_entry = DownloadEntryToProto(entries[i]);
120 }
121 return proto;
122 }
123
124 // static
HttpRequestHeaderToProto(const std::pair<std::string,std::string> & header)125 download_pb::HttpRequestHeader DownloadDBConversions::HttpRequestHeaderToProto(
126 const std::pair<std::string, std::string>& header) {
127 download_pb::HttpRequestHeader proto;
128 if (header.first.empty())
129 return proto;
130
131 proto.set_key(header.first);
132 proto.set_value(header.second);
133 return proto;
134 }
135
136 // static
137 std::pair<std::string, std::string>
HttpRequestHeaderFromProto(const download_pb::HttpRequestHeader & proto)138 DownloadDBConversions::HttpRequestHeaderFromProto(
139 const download_pb::HttpRequestHeader& proto) {
140 if (proto.key().empty())
141 return std::pair<std::string, std::string>();
142
143 return std::make_pair(proto.key(), proto.value());
144 }
145
146 // static
InProgressInfoToProto(const InProgressInfo & in_progress_info)147 download_pb::InProgressInfo DownloadDBConversions::InProgressInfoToProto(
148 const InProgressInfo& in_progress_info) {
149 download_pb::InProgressInfo proto;
150 for (size_t i = 0; i < in_progress_info.url_chain.size(); ++i)
151 proto.add_url_chain(in_progress_info.url_chain[i].spec());
152 proto.set_referrer_url(in_progress_info.referrer_url.spec());
153 proto.set_site_url(in_progress_info.site_url.spec());
154 proto.set_tab_url(in_progress_info.tab_url.spec());
155 proto.set_tab_referrer_url(in_progress_info.tab_referrer_url.spec());
156 proto.set_fetch_error_body(in_progress_info.fetch_error_body);
157 for (const auto& header : in_progress_info.request_headers) {
158 auto* proto_header = proto.add_request_headers();
159 *proto_header = HttpRequestHeaderToProto(header);
160 }
161 proto.set_etag(in_progress_info.etag);
162 proto.set_last_modified(in_progress_info.last_modified);
163 proto.set_mime_type(in_progress_info.mime_type);
164 proto.set_original_mime_type(in_progress_info.original_mime_type);
165 proto.set_total_bytes(in_progress_info.total_bytes);
166 base::Pickle current_path;
167 in_progress_info.current_path.WriteToPickle(¤t_path);
168 proto.set_current_path(current_path.data(), current_path.size());
169 base::Pickle target_path;
170 in_progress_info.target_path.WriteToPickle(&target_path);
171 proto.set_target_path(target_path.data(), target_path.size());
172 proto.set_received_bytes(in_progress_info.received_bytes);
173 proto.set_start_time(
174 in_progress_info.start_time.is_null()
175 ? -1
176 : in_progress_info.start_time.ToDeltaSinceWindowsEpoch()
177 .InMilliseconds());
178 proto.set_end_time(in_progress_info.end_time.is_null()
179 ? -1
180 : in_progress_info.end_time.ToDeltaSinceWindowsEpoch()
181 .InMilliseconds());
182 for (size_t i = 0; i < in_progress_info.received_slices.size(); ++i) {
183 download_pb::ReceivedSlice* slice = proto.add_received_slices();
184 slice->set_received_bytes(
185 in_progress_info.received_slices[i].received_bytes);
186 slice->set_offset(in_progress_info.received_slices[i].offset);
187 slice->set_finished(in_progress_info.received_slices[i].finished);
188 }
189 proto.set_hash(in_progress_info.hash);
190 proto.set_transient(in_progress_info.transient);
191 proto.set_state(in_progress_info.state);
192 proto.set_danger_type(in_progress_info.danger_type);
193 proto.set_interrupt_reason(in_progress_info.interrupt_reason);
194 proto.set_paused(in_progress_info.paused);
195 proto.set_metered(in_progress_info.metered);
196 proto.set_bytes_wasted(in_progress_info.bytes_wasted);
197 proto.set_auto_resume_count(in_progress_info.auto_resume_count);
198 return proto;
199 }
200
201 // static
InProgressInfoFromProto(const download_pb::InProgressInfo & proto)202 InProgressInfo DownloadDBConversions::InProgressInfoFromProto(
203 const download_pb::InProgressInfo& proto) {
204 InProgressInfo info;
205 for (const auto& url : proto.url_chain())
206 info.url_chain.emplace_back(url);
207 info.referrer_url = GURL(proto.referrer_url());
208 info.site_url = GURL(proto.site_url());
209 info.tab_url = GURL(proto.tab_url());
210 info.tab_referrer_url = GURL(proto.tab_referrer_url());
211 info.fetch_error_body = proto.fetch_error_body();
212 for (const auto& header : proto.request_headers())
213 info.request_headers.emplace_back(HttpRequestHeaderFromProto(header));
214 info.etag = proto.etag();
215 info.last_modified = proto.last_modified();
216 info.mime_type = proto.mime_type();
217 info.original_mime_type = proto.original_mime_type();
218 info.total_bytes = proto.total_bytes();
219 base::PickleIterator current_path(
220 base::Pickle(proto.current_path().data(), proto.current_path().size()));
221 info.current_path.ReadFromPickle(¤t_path);
222 base::PickleIterator target_path(
223 base::Pickle(proto.target_path().data(), proto.target_path().size()));
224 info.target_path.ReadFromPickle(&target_path);
225 info.received_bytes = proto.received_bytes();
226 info.start_time =
227 proto.start_time() == -1
228 ? base::Time()
229 : base::Time::FromDeltaSinceWindowsEpoch(
230 base::TimeDelta::FromMilliseconds(proto.start_time()));
231 info.end_time =
232 proto.end_time() == -1
233 ? base::Time()
234 : base::Time::FromDeltaSinceWindowsEpoch(
235 base::TimeDelta::FromMilliseconds(proto.end_time()));
236
237 for (int i = 0; i < proto.received_slices_size(); ++i) {
238 info.received_slices.emplace_back(proto.received_slices(i).offset(),
239 proto.received_slices(i).received_bytes(),
240 proto.received_slices(i).finished());
241 }
242 info.hash = proto.hash();
243 info.transient = proto.transient();
244 info.state = static_cast<DownloadItem::DownloadState>(proto.state());
245 info.danger_type = static_cast<DownloadDangerType>(proto.danger_type());
246 info.interrupt_reason =
247 static_cast<DownloadInterruptReason>(proto.interrupt_reason());
248 info.paused = proto.paused();
249 info.metered = proto.metered();
250 info.bytes_wasted = proto.bytes_wasted();
251 info.auto_resume_count = proto.auto_resume_count();
252 return info;
253 }
254
UkmInfoFromProto(const download_pb::UkmInfo & proto)255 UkmInfo DownloadDBConversions::UkmInfoFromProto(
256 const download_pb::UkmInfo& proto) {
257 UkmInfo info;
258 info.download_source = DownloadSourceFromProto(proto.download_source());
259 info.ukm_download_id = proto.ukm_download_id();
260 return info;
261 }
262
UkmInfoToProto(const UkmInfo & info)263 download_pb::UkmInfo DownloadDBConversions::UkmInfoToProto(
264 const UkmInfo& info) {
265 download_pb::UkmInfo proto;
266 proto.set_download_source(DownloadSourceToProto(info.download_source));
267 proto.set_ukm_download_id(info.ukm_download_id);
268 return proto;
269 }
270
DownloadInfoFromProto(const download_pb::DownloadInfo & proto)271 DownloadInfo DownloadDBConversions::DownloadInfoFromProto(
272 const download_pb::DownloadInfo& proto) {
273 DownloadInfo info;
274 info.guid = proto.guid();
275 info.id = proto.id();
276 if (proto.has_ukm_info())
277 info.ukm_info = UkmInfoFromProto(proto.ukm_info());
278 if (proto.has_in_progress_info())
279 info.in_progress_info = InProgressInfoFromProto(proto.in_progress_info());
280 return info;
281 }
282
DownloadInfoToProto(const DownloadInfo & info)283 download_pb::DownloadInfo DownloadDBConversions::DownloadInfoToProto(
284 const DownloadInfo& info) {
285 download_pb::DownloadInfo proto;
286 proto.set_guid(info.guid);
287 proto.set_id(info.id);
288 if (info.ukm_info.has_value()) {
289 auto ukm_info = std::make_unique<download_pb::UkmInfo>(
290 UkmInfoToProto(info.ukm_info.value()));
291 proto.set_allocated_ukm_info(ukm_info.release());
292 }
293 if (info.in_progress_info.has_value()) {
294 auto in_progress_info = std::make_unique<download_pb::InProgressInfo>(
295 InProgressInfoToProto(info.in_progress_info.value()));
296 proto.set_allocated_in_progress_info(in_progress_info.release());
297 }
298 return proto;
299 }
300
DownloadDBEntryFromProto(const download_pb::DownloadDBEntry & proto)301 DownloadDBEntry DownloadDBConversions::DownloadDBEntryFromProto(
302 const download_pb::DownloadDBEntry& proto) {
303 DownloadDBEntry entry;
304 if (proto.has_download_info())
305 entry.download_info = DownloadInfoFromProto(proto.download_info());
306 return entry;
307 }
308
DownloadDBEntryToProto(const DownloadDBEntry & info)309 download_pb::DownloadDBEntry DownloadDBConversions::DownloadDBEntryToProto(
310 const DownloadDBEntry& info) {
311 download_pb::DownloadDBEntry proto;
312 if (info.download_info.has_value()) {
313 auto download_info = std::make_unique<download_pb::DownloadInfo>(
314 DownloadInfoToProto(info.download_info.value()));
315 proto.set_allocated_download_info(download_info.release());
316 }
317 return proto;
318 }
319
DownloadDBEntryFromDownloadEntry(const DownloadEntry & entry)320 DownloadDBEntry DownloadDBConversions::DownloadDBEntryFromDownloadEntry(
321 const DownloadEntry& entry) {
322 DownloadDBEntry db_entry;
323 DownloadInfo download_info;
324 download_info.guid = entry.guid;
325
326 UkmInfo ukm_info(entry.download_source, entry.ukm_download_id);
327
328 InProgressInfo in_progress_info;
329 in_progress_info.fetch_error_body = entry.fetch_error_body;
330 in_progress_info.request_headers = entry.request_headers;
331
332 download_info.ukm_info = ukm_info;
333 download_info.in_progress_info = in_progress_info;
334 db_entry.download_info = download_info;
335 return db_entry;
336 }
337
338 } // namespace download
339