Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: ios/chrome/browser/reading_list/reading_list_entry.cc

Issue 2451843002: Add Store+Sync to reading list. (Closed)
Patch Set: reading_list_model_unittests Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ios/chrome/browser/reading_list/reading_list_entry.h" 5 #include "ios/chrome/browser/reading_list/reading_list_entry.h"
6 6
7 #include "base/json/json_string_value_serializer.h"
7 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "components/sync/protocol/reading_list_specifics.pb.h"
10 #include "ios/chrome/browser/reading_list/proto/reading_list.pb.h"
11 #include "net/base/backoff_entry_serializer.h"
8 12
9 // The backoff time is the following: 10min, 10min, 1h, 2h, 2h..., starting 13 // The backoff time is the following: 10min, 10min, 1h, 2h, 2h..., starting
10 // after the first failure. 14 // after the first failure.
11 const net::BackoffEntry::Policy ReadingListEntry::kBackoffPolicy = { 15 const net::BackoffEntry::Policy ReadingListEntry::kBackoffPolicy = {
12 // Number of initial errors (in sequence) to ignore before applying 16 // Number of initial errors (in sequence) to ignore before applying
13 // exponential back-off rules. 17 // exponential back-off rules.
14 2, 18 2,
15 19
16 // Initial delay for exponential back-off in ms. 20 // Initial delay for exponential back-off in ms.
17 10 * 60 * 1000, // 10 minutes. 21 10 * 60 * 1000, // 10 minutes.
(...skipping 14 matching lines...) Expand all
32 36
33 true, // Don't use initial delay unless the last request was an error. 37 true, // Don't use initial delay unless the last request was an error.
34 }; 38 };
35 39
36 ReadingListEntry::ReadingListEntry(const GURL& url, const std::string& title) 40 ReadingListEntry::ReadingListEntry(const GURL& url, const std::string& title)
37 : ReadingListEntry(url, title, nullptr){}; 41 : ReadingListEntry(url, title, nullptr){};
38 42
39 ReadingListEntry::ReadingListEntry(const GURL& url, 43 ReadingListEntry::ReadingListEntry(const GURL& url,
40 const std::string& title, 44 const std::string& title,
41 std::unique_ptr<net::BackoffEntry> backoff) 45 std::unique_ptr<net::BackoffEntry> backoff)
46 : ReadingListEntry(url,
47 title,
48 0,
49 0,
50 WAITING,
51 GURL(),
52 0,
53 std::move(backoff)) {}
54
55 ReadingListEntry::ReadingListEntry(
56 const GURL& url,
57 const std::string& title,
58 int64_t creation_time,
59 int64_t update_time,
60 ReadingListEntry::DistillationState distilled_state,
61 const GURL& distilled_url,
62 int failed_download_counter,
63 std::unique_ptr<net::BackoffEntry> backoff)
42 : url_(url), 64 : url_(url),
43 title_(title), 65 title_(title),
44 distilled_state_(WAITING), 66 distilled_url_(distilled_url),
45 failed_download_counter_(0) { 67 distilled_state_(distilled_state),
68 failed_download_counter_(failed_download_counter),
69 creation_time_us_(creation_time),
70 update_time_us_(update_time) {
46 if (backoff) { 71 if (backoff) {
47 backoff_ = std::move(backoff); 72 backoff_ = std::move(backoff);
48 } else { 73 } else {
49 backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy); 74 backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy);
50 } 75 }
76 if (creation_time_us_ == 0) {
77 DCHECK(update_time_us_ == 0);
78 creation_time_us_ =
79 (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
80 update_time_us_ = creation_time_us_;
81 }
51 DCHECK(!url.is_empty()); 82 DCHECK(!url.is_empty());
52 DCHECK(url.is_valid()); 83 DCHECK(url.is_valid());
53 } 84 }
54 85
55 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry) 86 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry)
56 : url_(std::move(entry.url_)), 87 : url_(std::move(entry.url_)),
57 title_(std::move(entry.title_)), 88 title_(std::move(entry.title_)),
58 distilled_url_(std::move(entry.distilled_url_)), 89 distilled_url_(std::move(entry.distilled_url_)),
59 distilled_state_(std::move(entry.distilled_state_)), 90 distilled_state_(std::move(entry.distilled_state_)),
60 backoff_(std::move(entry.backoff_)), 91 backoff_(std::move(entry.backoff_)),
61 failed_download_counter_(std::move(entry.failed_download_counter_)) {} 92 failed_download_counter_(std::move(entry.failed_download_counter_)),
93 creation_time_us_(std::move(entry.creation_time_us_)),
94 update_time_us_(std::move(entry.update_time_us_)) {}
62 95
63 ReadingListEntry::~ReadingListEntry() {} 96 ReadingListEntry::~ReadingListEntry() {}
64 97
65 const GURL& ReadingListEntry::URL() const { 98 const GURL& ReadingListEntry::URL() const {
66 return url_; 99 return url_;
67 } 100 }
68 101
69 const std::string& ReadingListEntry::Title() const { 102 const std::string& ReadingListEntry::Title() const {
70 return title_; 103 return title_;
71 } 104 }
(...skipping 14 matching lines...) Expand all
86 return failed_download_counter_; 119 return failed_download_counter_;
87 } 120 }
88 121
89 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) { 122 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) {
90 url_ = std::move(other.url_); 123 url_ = std::move(other.url_);
91 title_ = std::move(other.title_); 124 title_ = std::move(other.title_);
92 distilled_url_ = std::move(other.distilled_url_); 125 distilled_url_ = std::move(other.distilled_url_);
93 distilled_state_ = std::move(other.distilled_state_); 126 distilled_state_ = std::move(other.distilled_state_);
94 backoff_ = std::move(other.backoff_); 127 backoff_ = std::move(other.backoff_);
95 failed_download_counter_ = std::move(other.failed_download_counter_); 128 failed_download_counter_ = std::move(other.failed_download_counter_);
129 creation_time_us_ = std::move(other.creation_time_us_);
130 update_time_us_ = std::move(other.update_time_us_);
96 return *this; 131 return *this;
97 } 132 }
98 133
99 bool ReadingListEntry::operator==(const ReadingListEntry& other) const { 134 bool ReadingListEntry::operator==(const ReadingListEntry& other) const {
100 return url_ == other.url_; 135 return url_ == other.url_;
101 } 136 }
102 137
103 void ReadingListEntry::SetTitle(const std::string& title) { 138 void ReadingListEntry::SetTitle(const std::string& title) {
104 title_ = title; 139 title_ = title;
105 } 140 }
(...skipping 13 matching lines...) Expand all
119 // non-error state to an error state. 154 // non-error state to an error state.
120 if ((distilled_state == WILL_RETRY || distilled_state == ERROR) && 155 if ((distilled_state == WILL_RETRY || distilled_state == ERROR) &&
121 distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) { 156 distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) {
122 backoff_->InformOfRequest(false); 157 backoff_->InformOfRequest(false);
123 failed_download_counter_++; 158 failed_download_counter_++;
124 } 159 }
125 160
126 distilled_state_ = distilled_state; 161 distilled_state_ = distilled_state;
127 distilled_url_ = GURL(); 162 distilled_url_ = GURL();
128 } 163 }
164
165 int64_t ReadingListEntry::UpdateTime() const {
166 return update_time_us_;
167 }
168
169 void ReadingListEntry::MarkEntryUpdated() {
170 update_time_us_ =
171 (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
172 }
173
174 // static
175 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListLocal(
176 const reading_list::ReadingListLocal& pb_entry) {
177 if (!pb_entry.has_url()) {
178 return nullptr;
179 }
180 GURL url(pb_entry.url());
181 if (url.is_empty() || !url.is_valid()) {
182 return nullptr;
183 }
184 std::string title;
185 if (pb_entry.has_title()) {
186 title = pb_entry.title();
187 }
188
189 int64_t creation_time_us = 0;
190 if (pb_entry.has_creation_time_us()) {
191 creation_time_us = pb_entry.creation_time_us();
192 }
193
194 int64_t update_time_us = 0;
195 if (pb_entry.has_update_time_us()) {
196 update_time_us = pb_entry.update_time_us();
197 }
198
199 ReadingListEntry::DistillationState distillation_state =
200 ReadingListEntry::WAITING;
201 if (pb_entry.has_distillation_state()) {
202 switch (pb_entry.distillation_state()) {
203 case reading_list::ReadingListLocal::WAITING:
204 distillation_state = ReadingListEntry::WAITING;
205 break;
206 case reading_list::ReadingListLocal::PROCESSING:
207 distillation_state = ReadingListEntry::PROCESSING;
208 break;
209 case reading_list::ReadingListLocal::PROCESSED:
210 distillation_state = ReadingListEntry::PROCESSED;
211 break;
212 case reading_list::ReadingListLocal::WILL_RETRY:
213 distillation_state = ReadingListEntry::WILL_RETRY;
214 break;
215 case reading_list::ReadingListLocal::ERROR:
216 distillation_state = ReadingListEntry::ERROR;
217 break;
218 }
219 }
220
221 GURL distilled_url;
222 if (pb_entry.has_distilled_url()) {
223 distilled_url = GURL(pb_entry.distilled_url());
224 }
225
226 int64_t failed_download_counter = 0;
227 if (pb_entry.has_failed_download_counter()) {
228 failed_download_counter = pb_entry.failed_download_counter();
229 }
230
231 std::unique_ptr<net::BackoffEntry> backoff;
232 if (pb_entry.has_backoff()) {
233 JSONStringValueDeserializer deserializer(pb_entry.backoff());
234 std::unique_ptr<base::Value> value(
235 deserializer.Deserialize(nullptr, nullptr));
236 if (value) {
237 backoff = net::BackoffEntrySerializer::DeserializeFromValue(
238 *value, &kBackoffPolicy, nullptr, base::Time::Now());
239 }
240 }
241
242 return base::WrapUnique<ReadingListEntry>(new ReadingListEntry(
243 url, title, creation_time_us, update_time_us, distillation_state,
244 distilled_url, failed_download_counter, std::move(backoff)));
245 }
246
247 // static
248 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListSpecifics(
249 const sync_pb::ReadingListSpecifics& pb_entry) {
250 if (!pb_entry.has_url()) {
251 return nullptr;
252 }
253 GURL url(pb_entry.url());
254 if (url.is_empty() || !url.is_valid()) {
255 return nullptr;
256 }
257 std::string title;
258 if (pb_entry.has_title()) {
259 title = pb_entry.title();
260 }
261
262 int64_t creation_time_us = 0;
263 if (pb_entry.has_creation_time_us()) {
264 creation_time_us = pb_entry.creation_time_us();
265 }
266
267 int64_t update_time_us = 0;
268 if (pb_entry.has_update_time_us()) {
269 update_time_us = pb_entry.update_time_us();
270 }
271
272 return base::WrapUnique<ReadingListEntry>(
273 new ReadingListEntry(url, title, creation_time_us, update_time_us,
274 WAITING, GURL(), 0, nullptr));
275 }
276
277 void ReadingListEntry::MergeLocalStateFrom(ReadingListEntry& other) {
278 distilled_url_ = std::move(other.distilled_url_);
279 distilled_state_ = std::move(other.distilled_state_);
280 backoff_ = std::move(other.backoff_);
281 failed_download_counter_ = std::move(other.failed_download_counter_);
282 }
283
284 std::unique_ptr<reading_list::ReadingListLocal>
285 ReadingListEntry::AsReadingListLocal(bool read) const {
286 std::unique_ptr<reading_list::ReadingListLocal> pb_entry =
287 base::MakeUnique<reading_list::ReadingListLocal>();
288
289 // URL is used as the key for the database and sync as there is only one entry
290 // per URL.
291 pb_entry->set_entry_id(URL().spec());
292 pb_entry->set_title(Title());
293 pb_entry->set_url(URL().spec());
294 pb_entry->set_creation_time_us(creation_time_us_);
295 pb_entry->set_update_time_us(UpdateTime());
296
297 if (read) {
298 pb_entry->set_status(reading_list::ReadingListLocal::READ);
299 } else {
300 pb_entry->set_status(reading_list::ReadingListLocal::UNREAD);
301 }
302
303 reading_list::ReadingListLocal::DistillationState distilation_state;
304 switch (DistilledState()) {
305 case ReadingListEntry::WAITING:
306 distilation_state = reading_list::ReadingListLocal::WAITING;
307 break;
308 case ReadingListEntry::PROCESSING:
309 distilation_state = reading_list::ReadingListLocal::PROCESSING;
310 break;
311 case ReadingListEntry::PROCESSED:
312 distilation_state = reading_list::ReadingListLocal::PROCESSED;
313 break;
314 case ReadingListEntry::WILL_RETRY:
315 distilation_state = reading_list::ReadingListLocal::WILL_RETRY;
316 break;
317 case ReadingListEntry::ERROR:
318 distilation_state = reading_list::ReadingListLocal::ERROR;
319 break;
320 }
321 pb_entry->set_distillation_state(distilation_state);
322 if (DistilledURL().is_valid()) {
323 pb_entry->set_distilled_url(DistilledURL().spec());
324 }
325 pb_entry->set_failed_download_counter(failed_download_counter_);
326
327 if (backoff_) {
328 std::unique_ptr<base::Value> backoff =
329 net::BackoffEntrySerializer::SerializeToValue(*backoff_,
330 base::Time::Now());
331
332 std::string output;
333 JSONStringValueSerializer serializer(&output);
334 serializer.Serialize(*backoff);
335 pb_entry->set_backoff(output);
336 }
337 return pb_entry;
338 }
339
340 std::unique_ptr<sync_pb::ReadingListSpecifics>
341 ReadingListEntry::AsReadingListSpecifics(bool read) const {
342 std::unique_ptr<sync_pb::ReadingListSpecifics> pb_entry =
343 base::MakeUnique<sync_pb::ReadingListSpecifics>();
344
345 // URL is used as the key for the database and sync as there is only one entry
346 // per URL.
347 pb_entry->set_entry_id(URL().spec());
348 pb_entry->set_title(Title());
349 pb_entry->set_url(URL().spec());
350 pb_entry->set_creation_time_us(creation_time_us_);
351 pb_entry->set_update_time_us(UpdateTime());
352
353 if (read) {
354 pb_entry->set_status(sync_pb::ReadingListSpecifics::READ);
355 } else {
356 pb_entry->set_status(sync_pb::ReadingListSpecifics::UNREAD);
357 }
358
359 return pb_entry;
360 }
361
362 bool ReadingListEntry::CompareEntryUpdateTime(const ReadingListEntry& lhs,
363 const ReadingListEntry& rhs) {
364 return lhs.UpdateTime() > rhs.UpdateTime();
365 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698