OLD | NEW |
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 Loading... |
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, title, 0, 0, WAITING, GURL(), std::move(backoff)) {} |
| 47 |
| 48 ReadingListEntry::ReadingListEntry( |
| 49 const GURL& url, |
| 50 const std::string& title, |
| 51 int64_t creation_time, |
| 52 int64_t update_time, |
| 53 ReadingListEntry::DistillationState distilled_state, |
| 54 const GURL& distilled_url, |
| 55 std::unique_ptr<net::BackoffEntry> backoff) |
42 : url_(url), | 56 : url_(url), |
43 title_(title), | 57 title_(title), |
44 distilled_state_(WAITING), | 58 distilled_url_(distilled_url), |
45 failed_download_counter_(0) { | 59 distilled_state_(distilled_state), |
| 60 failed_download_counter_(0), |
| 61 creation_time_us_(creation_time), |
| 62 update_time_us_(update_time) { |
46 if (backoff) { | 63 if (backoff) { |
47 backoff_ = std::move(backoff); | 64 backoff_ = std::move(backoff); |
48 } else { | 65 } else { |
49 backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy); | 66 backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy); |
50 } | 67 } |
| 68 if (creation_time_us_ == 0) { |
| 69 DCHECK(update_time_us_ == 0); |
| 70 creation_time_us_ = |
| 71 (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); |
| 72 update_time_us_ = creation_time_us_; |
| 73 } |
51 DCHECK(!url.is_empty()); | 74 DCHECK(!url.is_empty()); |
52 DCHECK(url.is_valid()); | 75 DCHECK(url.is_valid()); |
53 } | 76 } |
54 | 77 |
55 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry) | 78 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry) |
56 : url_(std::move(entry.url_)), | 79 : url_(std::move(entry.url_)), |
57 title_(std::move(entry.title_)), | 80 title_(std::move(entry.title_)), |
58 distilled_url_(std::move(entry.distilled_url_)), | 81 distilled_url_(std::move(entry.distilled_url_)), |
59 distilled_state_(std::move(entry.distilled_state_)), | 82 distilled_state_(std::move(entry.distilled_state_)), |
60 backoff_(std::move(entry.backoff_)), | 83 backoff_(std::move(entry.backoff_)), |
61 failed_download_counter_(std::move(entry.failed_download_counter_)) {} | 84 failed_download_counter_(std::move(entry.failed_download_counter_)), |
| 85 creation_time_us_(std::move(entry.creation_time_us_)), |
| 86 update_time_us_(std::move(entry.update_time_us_)) {} |
62 | 87 |
63 ReadingListEntry::~ReadingListEntry() {} | 88 ReadingListEntry::~ReadingListEntry() {} |
64 | 89 |
65 const GURL& ReadingListEntry::URL() const { | 90 const GURL& ReadingListEntry::URL() const { |
66 return url_; | 91 return url_; |
67 } | 92 } |
68 | 93 |
69 const std::string& ReadingListEntry::Title() const { | 94 const std::string& ReadingListEntry::Title() const { |
70 return title_; | 95 return title_; |
71 } | 96 } |
(...skipping 14 matching lines...) Expand all Loading... |
86 return failed_download_counter_; | 111 return failed_download_counter_; |
87 } | 112 } |
88 | 113 |
89 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) { | 114 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) { |
90 url_ = std::move(other.url_); | 115 url_ = std::move(other.url_); |
91 title_ = std::move(other.title_); | 116 title_ = std::move(other.title_); |
92 distilled_url_ = std::move(other.distilled_url_); | 117 distilled_url_ = std::move(other.distilled_url_); |
93 distilled_state_ = std::move(other.distilled_state_); | 118 distilled_state_ = std::move(other.distilled_state_); |
94 backoff_ = std::move(other.backoff_); | 119 backoff_ = std::move(other.backoff_); |
95 failed_download_counter_ = std::move(other.failed_download_counter_); | 120 failed_download_counter_ = std::move(other.failed_download_counter_); |
| 121 creation_time_us_ = std::move(other.creation_time_us_); |
| 122 update_time_us_ = std::move(other.update_time_us_); |
96 return *this; | 123 return *this; |
97 } | 124 } |
98 | 125 |
99 bool ReadingListEntry::operator==(const ReadingListEntry& other) const { | 126 bool ReadingListEntry::operator==(const ReadingListEntry& other) const { |
100 return url_ == other.url_; | 127 return url_ == other.url_; |
101 } | 128 } |
102 | 129 |
103 void ReadingListEntry::SetTitle(const std::string& title) { | 130 void ReadingListEntry::SetTitle(const std::string& title) { |
104 title_ = title; | 131 title_ = title; |
105 } | 132 } |
(...skipping 13 matching lines...) Expand all Loading... |
119 // non-error state to an error state. | 146 // non-error state to an error state. |
120 if ((distilled_state == WILL_RETRY || distilled_state == ERROR) && | 147 if ((distilled_state == WILL_RETRY || distilled_state == ERROR) && |
121 distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) { | 148 distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) { |
122 backoff_->InformOfRequest(false); | 149 backoff_->InformOfRequest(false); |
123 failed_download_counter_++; | 150 failed_download_counter_++; |
124 } | 151 } |
125 | 152 |
126 distilled_state_ = distilled_state; | 153 distilled_state_ = distilled_state; |
127 distilled_url_ = GURL(); | 154 distilled_url_ = GURL(); |
128 } | 155 } |
| 156 |
| 157 int64_t ReadingListEntry::UpdateTime() const { |
| 158 return update_time_us_; |
| 159 } |
| 160 |
| 161 void ReadingListEntry::MarkEntryUpdated() { |
| 162 update_time_us_ = |
| 163 (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); |
| 164 } |
| 165 |
| 166 // static |
| 167 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListLocal( |
| 168 const reading_list::ReadingListLocal& pb_entry) { |
| 169 if (!pb_entry.has_url()) { |
| 170 return nullptr; |
| 171 } |
| 172 GURL url(pb_entry.url()); |
| 173 if (url.is_empty() || !url.is_valid()) { |
| 174 return nullptr; |
| 175 } |
| 176 std::string title; |
| 177 if (pb_entry.has_title()) { |
| 178 title = pb_entry.title(); |
| 179 } |
| 180 |
| 181 int64_t creation_time_us = 0; |
| 182 if (pb_entry.has_creation_time_us()) { |
| 183 creation_time_us = pb_entry.creation_time_us(); |
| 184 } |
| 185 |
| 186 int64_t update_time_us = 0; |
| 187 if (pb_entry.has_update_time_us()) { |
| 188 update_time_us = pb_entry.update_time_us(); |
| 189 } |
| 190 |
| 191 ReadingListEntry::DistillationState distillation_state = |
| 192 ReadingListEntry::WAITING; |
| 193 if (pb_entry.has_distillation_state()) { |
| 194 switch (pb_entry.distillation_state()) { |
| 195 case reading_list::ReadingListLocal::WAITING: |
| 196 distillation_state = ReadingListEntry::WAITING; |
| 197 case reading_list::ReadingListLocal::PROCESSING: |
| 198 distillation_state = ReadingListEntry::PROCESSING; |
| 199 case reading_list::ReadingListLocal::PROCESSED: |
| 200 distillation_state = ReadingListEntry::PROCESSED; |
| 201 case reading_list::ReadingListLocal::WILL_RETRY: |
| 202 distillation_state = ReadingListEntry::WILL_RETRY; |
| 203 case reading_list::ReadingListLocal::ERROR: |
| 204 distillation_state = ReadingListEntry::ERROR; |
| 205 } |
| 206 } |
| 207 |
| 208 GURL distilled_url; |
| 209 if (pb_entry.has_distilled_url()) { |
| 210 distilled_url = GURL(pb_entry.distilled_url()); |
| 211 } |
| 212 |
| 213 std::unique_ptr<net::BackoffEntry> backoff; |
| 214 if (pb_entry.has_backoff()) { |
| 215 JSONStringValueDeserializer deserializer(pb_entry.backoff()); |
| 216 std::unique_ptr<base::Value> value( |
| 217 deserializer.Deserialize(nullptr, nullptr)); |
| 218 if (value) { |
| 219 backoff = net::BackoffEntrySerializer::DeserializeFromValue( |
| 220 *value, &kBackoffPolicy, nullptr, base::Time::Now()); |
| 221 } |
| 222 } |
| 223 |
| 224 return base::WrapUnique<ReadingListEntry>(new ReadingListEntry( |
| 225 url, title, creation_time_us, update_time_us, distillation_state, |
| 226 distilled_url, std::move(backoff))); |
| 227 } |
| 228 |
| 229 // static |
| 230 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListSpecifics( |
| 231 const sync_pb::ReadingListSpecifics& pb_entry) { |
| 232 if (!pb_entry.has_url()) { |
| 233 return nullptr; |
| 234 } |
| 235 GURL url(pb_entry.url()); |
| 236 if (url.is_empty() || !url.is_valid()) { |
| 237 return nullptr; |
| 238 } |
| 239 std::string title; |
| 240 if (pb_entry.has_title()) { |
| 241 title = pb_entry.title(); |
| 242 } |
| 243 |
| 244 int64_t creation_time_us = 0; |
| 245 if (pb_entry.has_creation_time_us()) { |
| 246 creation_time_us = pb_entry.creation_time_us(); |
| 247 } |
| 248 |
| 249 int64_t update_time_us = 0; |
| 250 if (pb_entry.has_update_time_us()) { |
| 251 update_time_us = pb_entry.update_time_us(); |
| 252 } |
| 253 |
| 254 return base::WrapUnique<ReadingListEntry>(new ReadingListEntry( |
| 255 url, title, creation_time_us, update_time_us, WAITING, GURL(), nullptr)); |
| 256 } |
| 257 |
| 258 void ReadingListEntry::MergeLocalStateFrom(ReadingListEntry& other) { |
| 259 distilled_url_ = std::move(other.distilled_url_); |
| 260 distilled_state_ = std::move(other.distilled_state_); |
| 261 backoff_ = std::move(other.backoff_); |
| 262 failed_download_counter_ = std::move(other.failed_download_counter_); |
| 263 } |
| 264 |
| 265 std::unique_ptr<reading_list::ReadingListLocal> |
| 266 ReadingListEntry::AsReadingListLocal(bool read) const { |
| 267 std::unique_ptr<reading_list::ReadingListLocal> pb_entry = |
| 268 base::MakeUnique<reading_list::ReadingListLocal>(); |
| 269 |
| 270 // URL is used as the key for the database and sync as there is only one entry |
| 271 // per URL. |
| 272 pb_entry->set_entry_id(URL().spec()); |
| 273 pb_entry->set_title(Title()); |
| 274 pb_entry->set_url(URL().spec()); |
| 275 pb_entry->set_creation_time_us(creation_time_us_); |
| 276 pb_entry->set_update_time_us(UpdateTime()); |
| 277 |
| 278 if (read) { |
| 279 pb_entry->set_status(reading_list::ReadingListLocal::READ); |
| 280 } else { |
| 281 pb_entry->set_status(reading_list::ReadingListLocal::UNREAD); |
| 282 } |
| 283 |
| 284 reading_list::ReadingListLocal::DistillationState distilation_state; |
| 285 switch (DistilledState()) { |
| 286 case ReadingListEntry::WAITING: |
| 287 distilation_state = reading_list::ReadingListLocal::WAITING; |
| 288 case ReadingListEntry::PROCESSING: |
| 289 distilation_state = reading_list::ReadingListLocal::PROCESSING; |
| 290 case ReadingListEntry::PROCESSED: |
| 291 distilation_state = reading_list::ReadingListLocal::PROCESSED; |
| 292 case ReadingListEntry::WILL_RETRY: |
| 293 distilation_state = reading_list::ReadingListLocal::WILL_RETRY; |
| 294 case ReadingListEntry::ERROR: |
| 295 distilation_state = reading_list::ReadingListLocal::ERROR; |
| 296 } |
| 297 pb_entry->set_distillation_state(distilation_state); |
| 298 if (DistilledURL().is_valid()) { |
| 299 pb_entry->set_distilled_url(DistilledURL().spec()); |
| 300 } |
| 301 |
| 302 if (backoff_) { |
| 303 std::unique_ptr<base::Value> backoff = |
| 304 net::BackoffEntrySerializer::SerializeToValue(*backoff_, |
| 305 base::Time::Now()); |
| 306 |
| 307 std::string output; |
| 308 JSONStringValueSerializer serializer(&output); |
| 309 serializer.Serialize(*backoff); |
| 310 pb_entry->set_backoff(output); |
| 311 } |
| 312 return pb_entry; |
| 313 } |
| 314 |
| 315 std::unique_ptr<sync_pb::ReadingListSpecifics> |
| 316 ReadingListEntry::AsReadingListSpecifics(bool read) const { |
| 317 std::unique_ptr<sync_pb::ReadingListSpecifics> pb_entry = |
| 318 base::MakeUnique<sync_pb::ReadingListSpecifics>(); |
| 319 |
| 320 // URL is used as the key for the database and sync as there is only one entry |
| 321 // per URL. |
| 322 pb_entry->set_entry_id(URL().spec()); |
| 323 pb_entry->set_title(Title()); |
| 324 pb_entry->set_url(URL().spec()); |
| 325 pb_entry->set_creation_time_us(creation_time_us_); |
| 326 pb_entry->set_update_time_us(UpdateTime()); |
| 327 |
| 328 if (read) { |
| 329 pb_entry->set_status(sync_pb::ReadingListSpecifics::READ); |
| 330 } else { |
| 331 pb_entry->set_status(sync_pb::ReadingListSpecifics::UNREAD); |
| 332 } |
| 333 |
| 334 return pb_entry; |
| 335 } |
| 336 |
| 337 bool ReadingListEntry::CompareEntryUpdateTime(const ReadingListEntry& lhs, |
| 338 const ReadingListEntry& rhs) { |
| 339 return lhs.UpdateTime() > rhs.UpdateTime(); |
| 340 } |
OLD | NEW |