| 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 namespace { | 13 namespace { | 
| 10 // URL used to open offline pages. | 14 // URL used to open offline pages. | 
| 11 // This variable will be moved to chrome_url_constants. | 15 // This variable will be moved to chrome_url_constants. | 
| 12 const char kChromeUIOfflineURL[] = "chrome://offline/"; | 16 const char kChromeUIOfflineURL[] = "chrome://offline/"; | 
| 13 } | 17 } | 
| 14 | 18 | 
| 15 // The backoff time is the following: 10min, 10min, 1h, 2h, 2h..., starting | 19 // The backoff time is the following: 10min, 10min, 1h, 2h, 2h..., starting | 
| 16 // after the first failure. | 20 // after the first failure. | 
| 17 const net::BackoffEntry::Policy ReadingListEntry::kBackoffPolicy = { | 21 const net::BackoffEntry::Policy ReadingListEntry::kBackoffPolicy = { | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 38 | 42 | 
| 39     true,  // Don't use initial delay unless the last request was an error. | 43     true,  // Don't use initial delay unless the last request was an error. | 
| 40 }; | 44 }; | 
| 41 | 45 | 
| 42 ReadingListEntry::ReadingListEntry(const GURL& url, const std::string& title) | 46 ReadingListEntry::ReadingListEntry(const GURL& url, const std::string& title) | 
| 43     : ReadingListEntry(url, title, nullptr){}; | 47     : ReadingListEntry(url, title, nullptr){}; | 
| 44 | 48 | 
| 45 ReadingListEntry::ReadingListEntry(const GURL& url, | 49 ReadingListEntry::ReadingListEntry(const GURL& url, | 
| 46                                    const std::string& title, | 50                                    const std::string& title, | 
| 47                                    std::unique_ptr<net::BackoffEntry> backoff) | 51                                    std::unique_ptr<net::BackoffEntry> backoff) | 
|  | 52     : ReadingListEntry(url, | 
|  | 53                        title, | 
|  | 54                        0, | 
|  | 55                        0, | 
|  | 56                        WAITING, | 
|  | 57                        base::FilePath(), | 
|  | 58                        0, | 
|  | 59                        std::move(backoff)) {} | 
|  | 60 | 
|  | 61 ReadingListEntry::ReadingListEntry( | 
|  | 62     const GURL& url, | 
|  | 63     const std::string& title, | 
|  | 64     int64_t creation_time, | 
|  | 65     int64_t update_time, | 
|  | 66     ReadingListEntry::DistillationState distilled_state, | 
|  | 67     const base::FilePath& distilled_path, | 
|  | 68     int failed_download_counter, | 
|  | 69     std::unique_ptr<net::BackoffEntry> backoff) | 
| 48     : url_(url), | 70     : url_(url), | 
| 49       title_(title), | 71       title_(title), | 
| 50       distilled_state_(WAITING), | 72       distilled_path_(distilled_path), | 
| 51       failed_download_counter_(0) { | 73       distilled_state_(distilled_state), | 
|  | 74       failed_download_counter_(failed_download_counter), | 
|  | 75       creation_time_us_(creation_time), | 
|  | 76       update_time_us_(update_time) { | 
| 52   if (backoff) { | 77   if (backoff) { | 
| 53     backoff_ = std::move(backoff); | 78     backoff_ = std::move(backoff); | 
| 54   } else { | 79   } else { | 
| 55     backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy); | 80     backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy); | 
| 56   } | 81   } | 
|  | 82   if (creation_time_us_ == 0) { | 
|  | 83     DCHECK(update_time_us_ == 0); | 
|  | 84     creation_time_us_ = | 
|  | 85         (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); | 
|  | 86     update_time_us_ = creation_time_us_; | 
|  | 87   } | 
| 57   DCHECK(!url.is_empty()); | 88   DCHECK(!url.is_empty()); | 
| 58   DCHECK(url.is_valid()); | 89   DCHECK(url.is_valid()); | 
| 59 } | 90 } | 
| 60 | 91 | 
| 61 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry) | 92 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry) | 
| 62     : url_(std::move(entry.url_)), | 93     : url_(std::move(entry.url_)), | 
| 63       title_(std::move(entry.title_)), | 94       title_(std::move(entry.title_)), | 
| 64       distilled_path_(std::move(entry.distilled_path_)), | 95       distilled_path_(std::move(entry.distilled_path_)), | 
| 65       distilled_state_(std::move(entry.distilled_state_)), | 96       distilled_state_(std::move(entry.distilled_state_)), | 
| 66       backoff_(std::move(entry.backoff_)), | 97       backoff_(std::move(entry.backoff_)), | 
| 67       failed_download_counter_(std::move(entry.failed_download_counter_)) {} | 98       failed_download_counter_(std::move(entry.failed_download_counter_)), | 
|  | 99       creation_time_us_(std::move(entry.creation_time_us_)), | 
|  | 100       update_time_us_(std::move(entry.update_time_us_)) {} | 
| 68 | 101 | 
| 69 ReadingListEntry::~ReadingListEntry() {} | 102 ReadingListEntry::~ReadingListEntry() {} | 
| 70 | 103 | 
| 71 const GURL& ReadingListEntry::URL() const { | 104 const GURL& ReadingListEntry::URL() const { | 
| 72   return url_; | 105   return url_; | 
| 73 } | 106 } | 
| 74 | 107 | 
| 75 const std::string& ReadingListEntry::Title() const { | 108 const std::string& ReadingListEntry::Title() const { | 
| 76   return title_; | 109   return title_; | 
| 77 } | 110 } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 99   return failed_download_counter_; | 132   return failed_download_counter_; | 
| 100 } | 133 } | 
| 101 | 134 | 
| 102 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) { | 135 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) { | 
| 103   url_ = std::move(other.url_); | 136   url_ = std::move(other.url_); | 
| 104   title_ = std::move(other.title_); | 137   title_ = std::move(other.title_); | 
| 105   distilled_path_ = std::move(other.distilled_path_); | 138   distilled_path_ = std::move(other.distilled_path_); | 
| 106   distilled_state_ = std::move(other.distilled_state_); | 139   distilled_state_ = std::move(other.distilled_state_); | 
| 107   backoff_ = std::move(other.backoff_); | 140   backoff_ = std::move(other.backoff_); | 
| 108   failed_download_counter_ = std::move(other.failed_download_counter_); | 141   failed_download_counter_ = std::move(other.failed_download_counter_); | 
|  | 142   creation_time_us_ = std::move(other.creation_time_us_); | 
|  | 143   update_time_us_ = std::move(other.update_time_us_); | 
| 109   return *this; | 144   return *this; | 
| 110 } | 145 } | 
| 111 | 146 | 
| 112 bool ReadingListEntry::operator==(const ReadingListEntry& other) const { | 147 bool ReadingListEntry::operator==(const ReadingListEntry& other) const { | 
| 113   return url_ == other.url_; | 148   return url_ == other.url_; | 
| 114 } | 149 } | 
| 115 | 150 | 
| 116 void ReadingListEntry::SetTitle(const std::string& title) { | 151 void ReadingListEntry::SetTitle(const std::string& title) { | 
| 117   title_ = title; | 152   title_ = title; | 
| 118 } | 153 } | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 132   // non-error state to an error state. | 167   // non-error state to an error state. | 
| 133   if ((distilled_state == WILL_RETRY || distilled_state == ERROR) && | 168   if ((distilled_state == WILL_RETRY || distilled_state == ERROR) && | 
| 134       distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) { | 169       distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) { | 
| 135     backoff_->InformOfRequest(false); | 170     backoff_->InformOfRequest(false); | 
| 136     failed_download_counter_++; | 171     failed_download_counter_++; | 
| 137   } | 172   } | 
| 138 | 173 | 
| 139   distilled_state_ = distilled_state; | 174   distilled_state_ = distilled_state; | 
| 140   distilled_path_ = base::FilePath(); | 175   distilled_path_ = base::FilePath(); | 
| 141 } | 176 } | 
|  | 177 | 
|  | 178 int64_t ReadingListEntry::UpdateTime() const { | 
|  | 179   return update_time_us_; | 
|  | 180 } | 
|  | 181 | 
|  | 182 int64_t ReadingListEntry::CreationTime() const { | 
|  | 183   return creation_time_us_; | 
|  | 184 } | 
|  | 185 | 
|  | 186 void ReadingListEntry::MarkEntryUpdated() { | 
|  | 187   update_time_us_ = | 
|  | 188       (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); | 
|  | 189 } | 
|  | 190 | 
|  | 191 // static | 
|  | 192 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListLocal( | 
|  | 193     const reading_list::ReadingListLocal& pb_entry) { | 
|  | 194   if (!pb_entry.has_url()) { | 
|  | 195     return nullptr; | 
|  | 196   } | 
|  | 197   GURL url(pb_entry.url()); | 
|  | 198   if (url.is_empty() || !url.is_valid()) { | 
|  | 199     return nullptr; | 
|  | 200   } | 
|  | 201   std::string title; | 
|  | 202   if (pb_entry.has_title()) { | 
|  | 203     title = pb_entry.title(); | 
|  | 204   } | 
|  | 205 | 
|  | 206   int64_t creation_time_us = 0; | 
|  | 207   if (pb_entry.has_creation_time_us()) { | 
|  | 208     creation_time_us = pb_entry.creation_time_us(); | 
|  | 209   } | 
|  | 210 | 
|  | 211   int64_t update_time_us = 0; | 
|  | 212   if (pb_entry.has_update_time_us()) { | 
|  | 213     update_time_us = pb_entry.update_time_us(); | 
|  | 214   } | 
|  | 215 | 
|  | 216   ReadingListEntry::DistillationState distillation_state = | 
|  | 217       ReadingListEntry::WAITING; | 
|  | 218   if (pb_entry.has_distillation_state()) { | 
|  | 219     switch (pb_entry.distillation_state()) { | 
|  | 220       case reading_list::ReadingListLocal::WAITING: | 
|  | 221         distillation_state = ReadingListEntry::WAITING; | 
|  | 222         break; | 
|  | 223       case reading_list::ReadingListLocal::PROCESSING: | 
|  | 224         distillation_state = ReadingListEntry::PROCESSING; | 
|  | 225         break; | 
|  | 226       case reading_list::ReadingListLocal::PROCESSED: | 
|  | 227         distillation_state = ReadingListEntry::PROCESSED; | 
|  | 228         break; | 
|  | 229       case reading_list::ReadingListLocal::WILL_RETRY: | 
|  | 230         distillation_state = ReadingListEntry::WILL_RETRY; | 
|  | 231         break; | 
|  | 232       case reading_list::ReadingListLocal::ERROR: | 
|  | 233         distillation_state = ReadingListEntry::ERROR; | 
|  | 234         break; | 
|  | 235     } | 
|  | 236   } | 
|  | 237 | 
|  | 238   base::FilePath distilled_path; | 
|  | 239   if (pb_entry.has_distilled_path()) { | 
|  | 240     distilled_path = base::FilePath(pb_entry.distilled_path()); | 
|  | 241   } | 
|  | 242 | 
|  | 243   int64_t failed_download_counter = 0; | 
|  | 244   if (pb_entry.has_failed_download_counter()) { | 
|  | 245     failed_download_counter = pb_entry.failed_download_counter(); | 
|  | 246   } | 
|  | 247 | 
|  | 248   std::unique_ptr<net::BackoffEntry> backoff; | 
|  | 249   if (pb_entry.has_backoff()) { | 
|  | 250     JSONStringValueDeserializer deserializer(pb_entry.backoff()); | 
|  | 251     std::unique_ptr<base::Value> value( | 
|  | 252         deserializer.Deserialize(nullptr, nullptr)); | 
|  | 253     if (value) { | 
|  | 254       backoff = net::BackoffEntrySerializer::DeserializeFromValue( | 
|  | 255           *value, &kBackoffPolicy, nullptr, base::Time::Now()); | 
|  | 256     } | 
|  | 257   } | 
|  | 258 | 
|  | 259   return base::WrapUnique<ReadingListEntry>(new ReadingListEntry( | 
|  | 260       url, title, creation_time_us, update_time_us, distillation_state, | 
|  | 261       distilled_path, failed_download_counter, std::move(backoff))); | 
|  | 262 } | 
|  | 263 | 
|  | 264 // static | 
|  | 265 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListSpecifics( | 
|  | 266     const sync_pb::ReadingListSpecifics& pb_entry) { | 
|  | 267   if (!pb_entry.has_url()) { | 
|  | 268     return nullptr; | 
|  | 269   } | 
|  | 270   GURL url(pb_entry.url()); | 
|  | 271   if (url.is_empty() || !url.is_valid()) { | 
|  | 272     return nullptr; | 
|  | 273   } | 
|  | 274   std::string title; | 
|  | 275   if (pb_entry.has_title()) { | 
|  | 276     title = pb_entry.title(); | 
|  | 277   } | 
|  | 278 | 
|  | 279   int64_t creation_time_us = 0; | 
|  | 280   if (pb_entry.has_creation_time_us()) { | 
|  | 281     creation_time_us = pb_entry.creation_time_us(); | 
|  | 282   } | 
|  | 283 | 
|  | 284   int64_t update_time_us = 0; | 
|  | 285   if (pb_entry.has_update_time_us()) { | 
|  | 286     update_time_us = pb_entry.update_time_us(); | 
|  | 287   } | 
|  | 288 | 
|  | 289   return base::WrapUnique<ReadingListEntry>( | 
|  | 290       new ReadingListEntry(url, title, creation_time_us, update_time_us, | 
|  | 291                            WAITING, base::FilePath(), 0, nullptr)); | 
|  | 292 } | 
|  | 293 | 
|  | 294 void ReadingListEntry::MergeLocalStateFrom(ReadingListEntry& other) { | 
|  | 295   distilled_path_ = std::move(other.distilled_path_); | 
|  | 296   distilled_state_ = std::move(other.distilled_state_); | 
|  | 297   backoff_ = std::move(other.backoff_); | 
|  | 298   failed_download_counter_ = std::move(other.failed_download_counter_); | 
|  | 299 } | 
|  | 300 | 
|  | 301 std::unique_ptr<reading_list::ReadingListLocal> | 
|  | 302 ReadingListEntry::AsReadingListLocal(bool read) const { | 
|  | 303   std::unique_ptr<reading_list::ReadingListLocal> pb_entry = | 
|  | 304       base::MakeUnique<reading_list::ReadingListLocal>(); | 
|  | 305 | 
|  | 306   // URL is used as the key for the database and sync as there is only one entry | 
|  | 307   // per URL. | 
|  | 308   pb_entry->set_entry_id(URL().spec()); | 
|  | 309   pb_entry->set_title(Title()); | 
|  | 310   pb_entry->set_url(URL().spec()); | 
|  | 311   pb_entry->set_creation_time_us(CreationTime()); | 
|  | 312   pb_entry->set_update_time_us(UpdateTime()); | 
|  | 313 | 
|  | 314   if (read) { | 
|  | 315     pb_entry->set_status(reading_list::ReadingListLocal::READ); | 
|  | 316   } else { | 
|  | 317     pb_entry->set_status(reading_list::ReadingListLocal::UNREAD); | 
|  | 318   } | 
|  | 319 | 
|  | 320   reading_list::ReadingListLocal::DistillationState distilation_state; | 
|  | 321   switch (DistilledState()) { | 
|  | 322     case ReadingListEntry::WAITING: | 
|  | 323       distilation_state = reading_list::ReadingListLocal::WAITING; | 
|  | 324       break; | 
|  | 325     case ReadingListEntry::PROCESSING: | 
|  | 326       distilation_state = reading_list::ReadingListLocal::PROCESSING; | 
|  | 327       break; | 
|  | 328     case ReadingListEntry::PROCESSED: | 
|  | 329       distilation_state = reading_list::ReadingListLocal::PROCESSED; | 
|  | 330       break; | 
|  | 331     case ReadingListEntry::WILL_RETRY: | 
|  | 332       distilation_state = reading_list::ReadingListLocal::WILL_RETRY; | 
|  | 333       break; | 
|  | 334     case ReadingListEntry::ERROR: | 
|  | 335       distilation_state = reading_list::ReadingListLocal::ERROR; | 
|  | 336       break; | 
|  | 337   } | 
|  | 338   pb_entry->set_distillation_state(distilation_state); | 
|  | 339   if (!DistilledPath().empty()) { | 
|  | 340     pb_entry->set_distilled_path(DistilledPath().value()); | 
|  | 341   } | 
|  | 342   pb_entry->set_failed_download_counter(failed_download_counter_); | 
|  | 343 | 
|  | 344   if (backoff_) { | 
|  | 345     std::unique_ptr<base::Value> backoff = | 
|  | 346         net::BackoffEntrySerializer::SerializeToValue(*backoff_, | 
|  | 347                                                       base::Time::Now()); | 
|  | 348 | 
|  | 349     std::string output; | 
|  | 350     JSONStringValueSerializer serializer(&output); | 
|  | 351     serializer.Serialize(*backoff); | 
|  | 352     pb_entry->set_backoff(output); | 
|  | 353   } | 
|  | 354   return pb_entry; | 
|  | 355 } | 
|  | 356 | 
|  | 357 std::unique_ptr<sync_pb::ReadingListSpecifics> | 
|  | 358 ReadingListEntry::AsReadingListSpecifics(bool read) const { | 
|  | 359   std::unique_ptr<sync_pb::ReadingListSpecifics> pb_entry = | 
|  | 360       base::MakeUnique<sync_pb::ReadingListSpecifics>(); | 
|  | 361 | 
|  | 362   // URL is used as the key for the database and sync as there is only one entry | 
|  | 363   // per URL. | 
|  | 364   pb_entry->set_entry_id(URL().spec()); | 
|  | 365   pb_entry->set_title(Title()); | 
|  | 366   pb_entry->set_url(URL().spec()); | 
|  | 367   pb_entry->set_creation_time_us(CreationTime()); | 
|  | 368   pb_entry->set_update_time_us(UpdateTime()); | 
|  | 369 | 
|  | 370   if (read) { | 
|  | 371     pb_entry->set_status(sync_pb::ReadingListSpecifics::READ); | 
|  | 372   } else { | 
|  | 373     pb_entry->set_status(sync_pb::ReadingListSpecifics::UNREAD); | 
|  | 374   } | 
|  | 375 | 
|  | 376   return pb_entry; | 
|  | 377 } | 
|  | 378 | 
|  | 379 bool ReadingListEntry::CompareEntryUpdateTime(const ReadingListEntry& lhs, | 
|  | 380                                               const ReadingListEntry& rhs) { | 
|  | 381   return lhs.UpdateTime() > rhs.UpdateTime(); | 
|  | 382 } | 
| OLD | NEW | 
|---|