| 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_model_impl.h" | 5 #include "ios/chrome/browser/reading_list/reading_list_model_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/logging.h" |
| 9 #include "base/memory/ptr_util.h" |
| 7 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 8 #include "components/prefs/pref_service.h" | 11 #include "components/prefs/pref_service.h" |
| 9 #include "ios/chrome/browser/reading_list/reading_list_model_storage.h" | 12 #include "ios/chrome/browser/reading_list/reading_list_model_storage.h" |
| 10 #include "ios/chrome/browser/reading_list/reading_list_pref_names.h" | 13 #include "ios/chrome/browser/reading_list/reading_list_pref_names.h" |
| 11 #include "url/gurl.h" | 14 #include "url/gurl.h" |
| 12 | 15 |
| 13 ReadingListModelImpl::ReadingListModelImpl() | 16 ReadingListModelImpl::ReadingListModelImpl() |
| 14 : ReadingListModelImpl(nullptr, nullptr) {} | 17 : ReadingListModelImpl(nullptr, nullptr) {} |
| 15 | 18 |
| 16 ReadingListModelImpl::ReadingListModelImpl( | 19 ReadingListModelImpl::ReadingListModelImpl( |
| 17 std::unique_ptr<ReadingListModelStorage> storage, | 20 std::unique_ptr<ReadingListModelStorage> storage, |
| 18 PrefService* pref_service) | 21 PrefService* pref_service) |
| 19 : pref_service_(pref_service), has_unseen_(false) { | 22 : pref_service_(pref_service), |
| 23 has_unseen_(false), |
| 24 loaded_(false), |
| 25 weak_ptr_factory_(this) { |
| 26 DCHECK(CalledOnValidThread()); |
| 20 if (storage) { | 27 if (storage) { |
| 21 storage_layer_ = std::move(storage); | 28 storage_layer_ = std::move(storage); |
| 22 read_ = storage_layer_->LoadPersistentReadList(); | 29 storage_layer_->SetReadingListModel(this, this); |
| 23 unread_ = storage_layer_->LoadPersistentUnreadList(); | 30 } else { |
| 24 has_unseen_ = GetPersistentHasUnseen(); | 31 loaded_ = true; |
| 32 read_ = base::MakeUnique<ReadingListEntries>(); |
| 33 unread_ = base::MakeUnique<ReadingListEntries>(); |
| 25 } | 34 } |
| 26 loaded_ = true; | 35 has_unseen_ = GetPersistentHasUnseen(); |
| 27 } | 36 } |
| 28 | 37 |
| 29 ReadingListModelImpl::~ReadingListModelImpl() {} | 38 ReadingListModelImpl::~ReadingListModelImpl() {} |
| 30 | 39 |
| 40 void ReadingListModelImpl::StoreLoaded( |
| 41 std::unique_ptr<ReadingListEntries> unread, |
| 42 std::unique_ptr<ReadingListEntries> read) { |
| 43 DCHECK(CalledOnValidThread()); |
| 44 read_ = std::move(read); |
| 45 unread_ = std::move(unread); |
| 46 loaded_ = true; |
| 47 SortEntries(); |
| 48 for (auto& observer : observers_) |
| 49 observer.ReadingListModelLoaded(this); |
| 50 } |
| 51 |
| 31 void ReadingListModelImpl::Shutdown() { | 52 void ReadingListModelImpl::Shutdown() { |
| 53 DCHECK(CalledOnValidThread()); |
| 32 for (auto& observer : observers_) | 54 for (auto& observer : observers_) |
| 33 observer.ReadingListModelBeingDeleted(this); | 55 observer.ReadingListModelBeingDeleted(this); |
| 34 loaded_ = false; | 56 loaded_ = false; |
| 35 } | 57 } |
| 36 | 58 |
| 37 bool ReadingListModelImpl::loaded() const { | 59 bool ReadingListModelImpl::loaded() const { |
| 60 DCHECK(CalledOnValidThread()); |
| 38 return loaded_; | 61 return loaded_; |
| 39 } | 62 } |
| 40 | 63 |
| 41 size_t ReadingListModelImpl::unread_size() const { | 64 size_t ReadingListModelImpl::unread_size() const { |
| 42 DCHECK(loaded()); | 65 DCHECK(CalledOnValidThread()); |
| 43 return unread_.size(); | 66 if (!loaded()) |
| 67 return 0; |
| 68 return unread_->size(); |
| 44 } | 69 } |
| 45 | 70 |
| 46 size_t ReadingListModelImpl::read_size() const { | 71 size_t ReadingListModelImpl::read_size() const { |
| 47 DCHECK(loaded()); | 72 DCHECK(CalledOnValidThread()); |
| 48 return read_.size(); | 73 if (!loaded()) |
| 74 return 0; |
| 75 return read_->size(); |
| 49 } | 76 } |
| 50 | 77 |
| 51 bool ReadingListModelImpl::HasUnseenEntries() const { | 78 bool ReadingListModelImpl::HasUnseenEntries() const { |
| 52 DCHECK(loaded()); | 79 DCHECK(CalledOnValidThread()); |
| 80 if (!loaded()) |
| 81 return false; |
| 53 return unread_size() && has_unseen_; | 82 return unread_size() && has_unseen_; |
| 54 } | 83 } |
| 55 | 84 |
| 56 void ReadingListModelImpl::ResetUnseenEntries() { | 85 void ReadingListModelImpl::ResetUnseenEntries() { |
| 86 DCHECK(CalledOnValidThread()); |
| 57 DCHECK(loaded()); | 87 DCHECK(loaded()); |
| 58 has_unseen_ = false; | 88 has_unseen_ = false; |
| 59 if (storage_layer_ && !IsPerformingBatchUpdates()) | 89 if (!IsPerformingBatchUpdates()) |
| 60 SetPersistentHasUnseen(false); | 90 SetPersistentHasUnseen(false); |
| 61 } | 91 } |
| 62 | 92 |
| 63 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( | 93 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( |
| 64 size_t index) const { | 94 size_t index) const { |
| 95 DCHECK(CalledOnValidThread()); |
| 65 DCHECK(loaded()); | 96 DCHECK(loaded()); |
| 66 return unread_[index]; | 97 return unread_->at(index); |
| 67 } | 98 } |
| 68 | 99 |
| 69 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( | 100 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( |
| 70 size_t index) const { | 101 size_t index) const { |
| 102 DCHECK(CalledOnValidThread()); |
| 71 DCHECK(loaded()); | 103 DCHECK(loaded()); |
| 72 return read_[index]; | 104 return read_->at(index); |
| 73 } | 105 } |
| 74 | 106 |
| 75 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( | 107 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( |
| 76 const GURL& gurl) const { | 108 const GURL& gurl, |
| 109 bool* read) const { |
| 110 DCHECK(CalledOnValidThread()); |
| 77 DCHECK(loaded()); | 111 DCHECK(loaded()); |
| 112 return GetMutableEntryFromURL(gurl, read); |
| 113 } |
| 114 |
| 115 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( |
| 116 const GURL& gurl, |
| 117 bool* read) const { |
| 118 DCHECK(CalledOnValidThread()); |
| 119 DCHECK(loaded()); |
| 120 bool is_read; |
| 78 ReadingListEntry entry(gurl, std::string()); | 121 ReadingListEntry entry(gurl, std::string()); |
| 79 auto it = std::find(read_.begin(), read_.end(), entry); | 122 auto it = std::find(read_->begin(), read_->end(), entry); |
| 80 if (it == read_.end()) { | 123 is_read = true; |
| 81 it = std::find(unread_.begin(), unread_.end(), entry); | 124 if (it == read_->end()) { |
| 82 if (it == unread_.end()) | 125 it = std::find(unread_->begin(), unread_->end(), entry); |
| 126 is_read = false; |
| 127 if (it == unread_->end()) |
| 83 return nullptr; | 128 return nullptr; |
| 84 } | 129 } |
| 130 if (read) { |
| 131 *read = is_read; |
| 132 } |
| 85 return &(*it); | 133 return &(*it); |
| 86 } | 134 } |
| 87 | 135 |
| 88 bool ReadingListModelImpl::CallbackEntryURL( | 136 bool ReadingListModelImpl::CallbackEntryURL( |
| 89 const GURL& url, | 137 const GURL& url, |
| 90 base::Callback<void(const ReadingListEntry&)> callback) const { | 138 base::Callback<void(const ReadingListEntry&)> callback) const { |
| 139 DCHECK(CalledOnValidThread()); |
| 91 DCHECK(loaded()); | 140 DCHECK(loaded()); |
| 92 const ReadingListEntry* entry = GetEntryFromURL(url); | 141 const ReadingListEntry* entry = GetMutableEntryFromURL(url, nullptr); |
| 93 if (entry) { | 142 if (entry) { |
| 94 callback.Run(*entry); | 143 callback.Run(*entry); |
| 95 return true; | 144 return true; |
| 96 } | 145 } |
| 97 return false; | 146 return false; |
| 98 } | 147 } |
| 99 | 148 |
| 149 void ReadingListModelImpl::MoveEntryFrom(ReadingListEntries* entries, |
| 150 const ReadingListEntry& entry, |
| 151 bool read) { |
| 152 auto result = std::find(entries->begin(), entries->end(), entry); |
| 153 DCHECK(result != entries->end()); |
| 154 int index = std::distance(entries->begin(), result); |
| 155 for (auto& observer : observers_) |
| 156 observer.ReadingListWillMoveEntry(this, index, read); |
| 157 entries->erase(result); |
| 158 } |
| 159 |
| 160 void ReadingListModelImpl::SyncAddEntry(std::unique_ptr<ReadingListEntry> entry, |
| 161 bool read) { |
| 162 DCHECK(CalledOnValidThread()); |
| 163 DCHECK(loaded()); |
| 164 // entry must not already exist. |
| 165 DCHECK(GetMutableEntryFromURL(entry->URL(), nullptr) == nullptr); |
| 166 if (read) { |
| 167 for (auto& observer : observers_) |
| 168 observer.ReadingListWillAddReadEntry(this, *entry); |
| 169 read_->insert(read_->begin(), std::move(*entry)); |
| 170 } else { |
| 171 for (auto& observer : observers_) |
| 172 observer.ReadingListWillAddUnreadEntry(this, *entry); |
| 173 has_unseen_ = true; |
| 174 SetPersistentHasUnseen(true); |
| 175 unread_->insert(unread_->begin(), std::move(*entry)); |
| 176 } |
| 177 for (auto& observer : observers_) |
| 178 observer.ReadingListDidApplyChanges(this); |
| 179 } |
| 180 |
| 181 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry( |
| 182 std::unique_ptr<ReadingListEntry> entry, |
| 183 bool read) { |
| 184 DCHECK(CalledOnValidThread()); |
| 185 DCHECK(loaded()); |
| 186 bool is_existing_entry_read; |
| 187 ReadingListEntry* existing_entry = |
| 188 GetMutableEntryFromURL(entry->URL(), &is_existing_entry_read); |
| 189 |
| 190 DCHECK(existing_entry); |
| 191 DCHECK(existing_entry->UpdateTime() < entry->UpdateTime()); |
| 192 |
| 193 // Merge local data in new entry. |
| 194 entry->MergeLocalStateFrom(*existing_entry); |
| 195 |
| 196 if (is_existing_entry_read) { |
| 197 MoveEntryFrom(read_.get(), *existing_entry, true); |
| 198 } else { |
| 199 MoveEntryFrom(unread_.get(), *existing_entry, false); |
| 200 } |
| 201 |
| 202 ReadingListEntries::iterator added_iterator; |
| 203 if (read) { |
| 204 read_->push_back(std::move(*entry)); |
| 205 added_iterator = read_->end() - 1; |
| 206 } else { |
| 207 unread_->push_back(std::move(*entry)); |
| 208 added_iterator = unread_->end() - 1; |
| 209 } |
| 210 for (auto& observer : observers_) |
| 211 observer.ReadingListDidApplyChanges(this); |
| 212 |
| 213 ReadingListEntry& merged_entry = *added_iterator; |
| 214 return &merged_entry; |
| 215 } |
| 216 |
| 217 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) { |
| 218 RemoveEntryByURLImpl(url, true); |
| 219 } |
| 220 |
| 100 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { | 221 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { |
| 222 RemoveEntryByURLImpl(url, false); |
| 223 } |
| 224 |
| 225 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, |
| 226 bool from_sync) { |
| 227 DCHECK(CalledOnValidThread()); |
| 101 DCHECK(loaded()); | 228 DCHECK(loaded()); |
| 102 const ReadingListEntry entry(url, std::string()); | 229 const ReadingListEntry entry(url, std::string()); |
| 103 | 230 |
| 104 auto result = std::find(unread_.begin(), unread_.end(), entry); | 231 auto result = std::find(unread_->begin(), unread_->end(), entry); |
| 105 if (result != unread_.end()) { | 232 if (result != unread_->end()) { |
| 106 for (auto& observer : observers_) { | 233 for (auto& observer : observers_) |
| 107 observer.ReadingListWillRemoveUnreadEntry( | 234 observer.ReadingListWillRemoveUnreadEntry( |
| 108 this, std::distance(unread_.begin(), result)); | 235 this, std::distance(unread_->begin(), result)); |
| 236 |
| 237 if (storage_layer_ && !from_sync) { |
| 238 storage_layer_->RemoveEntry(*result); |
| 109 } | 239 } |
| 110 unread_.erase(result); | 240 unread_->erase(result); |
| 111 if (storage_layer_ && !IsPerformingBatchUpdates()) | 241 |
| 112 storage_layer_->SavePersistentUnreadList(unread_); | |
| 113 for (auto& observer : observers_) | 242 for (auto& observer : observers_) |
| 114 observer.ReadingListDidApplyChanges(this); | 243 observer.ReadingListDidApplyChanges(this); |
| 115 return; | 244 return; |
| 116 } | 245 } |
| 117 | 246 |
| 118 result = std::find(read_.begin(), read_.end(), entry); | 247 result = std::find(read_->begin(), read_->end(), entry); |
| 119 if (result != read_.end()) { | 248 if (result != read_->end()) { |
| 120 for (auto& observer : observers_) { | 249 for (auto& observer : observers_) |
| 121 observer.ReadingListWillRemoveReadEntry( | 250 observer.ReadingListWillRemoveReadEntry( |
| 122 this, std::distance(read_.begin(), result)); | 251 this, std::distance(read_->begin(), result)); |
| 252 if (storage_layer_ && !from_sync) { |
| 253 storage_layer_->RemoveEntry(*result); |
| 123 } | 254 } |
| 124 read_.erase(result); | 255 read_->erase(result); |
| 125 if (storage_layer_ && !IsPerformingBatchUpdates()) | 256 |
| 126 storage_layer_->SavePersistentReadList(read_); | |
| 127 for (auto& observer : observers_) | 257 for (auto& observer : observers_) |
| 128 observer.ReadingListDidApplyChanges(this); | 258 observer.ReadingListDidApplyChanges(this); |
| 129 return; | 259 return; |
| 130 } | 260 } |
| 131 } | 261 } |
| 132 | 262 |
| 133 const ReadingListEntry& ReadingListModelImpl::AddEntry( | 263 const ReadingListEntry& ReadingListModelImpl::AddEntry( |
| 134 const GURL& url, | 264 const GURL& url, |
| 135 const std::string& title) { | 265 const std::string& title) { |
| 266 DCHECK(CalledOnValidThread()); |
| 136 DCHECK(loaded()); | 267 DCHECK(loaded()); |
| 137 RemoveEntryByURL(url); | 268 RemoveEntryByURL(url); |
| 138 | 269 |
| 139 std::string trimmedTitle(title); | 270 std::string trimmedTitle(title); |
| 140 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle); | 271 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle); |
| 141 | 272 |
| 142 ReadingListEntry entry(url, trimmedTitle); | 273 ReadingListEntry entry(url, trimmedTitle); |
| 143 for (auto& observer : observers_) | 274 for (auto& observer : observers_) |
| 144 observer.ReadingListWillAddUnreadEntry(this, entry); | 275 observer.ReadingListWillAddUnreadEntry(this, entry); |
| 145 unread_.insert(unread_.begin(), std::move(entry)); | |
| 146 has_unseen_ = true; | 276 has_unseen_ = true; |
| 147 if (storage_layer_ && !IsPerformingBatchUpdates()) { | 277 SetPersistentHasUnseen(true); |
| 148 storage_layer_->SavePersistentUnreadList(unread_); | 278 if (storage_layer_) { |
| 149 SetPersistentHasUnseen(true); | 279 storage_layer_->SaveEntry(entry, false); |
| 150 } | 280 } |
| 281 unread_->insert(unread_->begin(), std::move(entry)); |
| 282 |
| 151 for (auto& observer : observers_) | 283 for (auto& observer : observers_) |
| 152 observer.ReadingListDidApplyChanges(this); | 284 observer.ReadingListDidApplyChanges(this); |
| 153 return *unread_.begin(); | 285 return *unread_->begin(); |
| 154 } | 286 } |
| 155 | 287 |
| 156 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { | 288 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { |
| 289 DCHECK(CalledOnValidThread()); |
| 157 DCHECK(loaded()); | 290 DCHECK(loaded()); |
| 158 ReadingListEntry entry(url, std::string()); | 291 ReadingListEntry entry(url, std::string()); |
| 159 auto result = std::find(read_.begin(), read_.end(), entry); | 292 auto result = std::find(read_->begin(), read_->end(), entry); |
| 160 if (result == read_.end()) | 293 if (result == read_->end()) |
| 161 return; | 294 return; |
| 162 | 295 |
| 163 for (ReadingListModelObserver& observer : observers_) { | 296 for (ReadingListModelObserver& observer : observers_) { |
| 164 observer.ReadingListWillMoveEntry(this, | 297 observer.ReadingListWillMoveEntry( |
| 165 std::distance(read_.begin(), result)); | 298 this, std::distance(read_->begin(), result), true); |
| 166 } | 299 } |
| 167 | 300 |
| 168 unread_.insert(unread_.begin(), std::move(*result)); | 301 result->MarkEntryUpdated(); |
| 169 read_.erase(result); | 302 if (storage_layer_) { |
| 303 storage_layer_->SaveEntry(*result, false); |
| 304 } |
| 170 | 305 |
| 171 if (storage_layer_ && !IsPerformingBatchUpdates()) { | 306 unread_->insert(unread_->begin(), std::move(*result)); |
| 172 storage_layer_->SavePersistentUnreadList(read_); | 307 read_->erase(result); |
| 173 storage_layer_->SavePersistentReadList(unread_); | 308 |
| 174 } | |
| 175 for (ReadingListModelObserver& observer : observers_) { | 309 for (ReadingListModelObserver& observer : observers_) { |
| 176 observer.ReadingListDidApplyChanges(this); | 310 observer.ReadingListDidApplyChanges(this); |
| 177 } | 311 } |
| 178 } | 312 } |
| 179 | 313 |
| 180 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { | 314 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { |
| 315 DCHECK(CalledOnValidThread()); |
| 181 DCHECK(loaded()); | 316 DCHECK(loaded()); |
| 182 ReadingListEntry entry(url, std::string()); | 317 ReadingListEntry entry(url, std::string()); |
| 183 auto result = std::find(unread_.begin(), unread_.end(), entry); | 318 auto result = std::find(unread_->begin(), unread_->end(), entry); |
| 184 if (result == unread_.end()) | 319 if (result == unread_->end()) |
| 185 return; | 320 return; |
| 186 | 321 |
| 187 for (auto& observer : observers_) { | 322 for (auto& observer : observers_) |
| 188 observer.ReadingListWillMoveEntry(this, | 323 observer.ReadingListWillMoveEntry( |
| 189 std::distance(unread_.begin(), result)); | 324 this, std::distance(unread_->begin(), result), false); |
| 325 |
| 326 result->MarkEntryUpdated(); |
| 327 if (storage_layer_) { |
| 328 storage_layer_->SaveEntry(*result, true); |
| 190 } | 329 } |
| 191 | 330 |
| 192 read_.insert(read_.begin(), std::move(*result)); | 331 read_->insert(read_->begin(), std::move(*result)); |
| 193 unread_.erase(result); | 332 unread_->erase(result); |
| 194 | 333 |
| 195 if (storage_layer_ && !IsPerformingBatchUpdates()) { | |
| 196 storage_layer_->SavePersistentUnreadList(unread_); | |
| 197 storage_layer_->SavePersistentReadList(read_); | |
| 198 } | |
| 199 for (auto& observer : observers_) | 334 for (auto& observer : observers_) |
| 200 observer.ReadingListDidApplyChanges(this); | 335 observer.ReadingListDidApplyChanges(this); |
| 201 } | 336 } |
| 202 | 337 |
| 203 void ReadingListModelImpl::SetEntryTitle(const GURL& url, | 338 void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
| 204 const std::string& title) { | 339 const std::string& title) { |
| 340 DCHECK(CalledOnValidThread()); |
| 205 DCHECK(loaded()); | 341 DCHECK(loaded()); |
| 206 const ReadingListEntry entry(url, std::string()); | 342 const ReadingListEntry entry(url, std::string()); |
| 207 | 343 |
| 208 auto result = std::find(unread_.begin(), unread_.end(), entry); | 344 auto result = std::find(unread_->begin(), unread_->end(), entry); |
| 209 if (result != unread_.end()) { | 345 if (result != unread_->end()) { |
| 210 for (auto& observer : observers_) { | 346 for (auto& observer : observers_) |
| 211 observer.ReadingListWillUpdateUnreadEntry( | 347 observer.ReadingListWillUpdateUnreadEntry( |
| 212 this, std::distance(unread_.begin(), result)); | 348 this, std::distance(unread_->begin(), result)); |
| 349 result->SetTitle(title); |
| 350 |
| 351 if (storage_layer_) { |
| 352 storage_layer_->SaveEntry(*result, false); |
| 213 } | 353 } |
| 214 result->SetTitle(title); | |
| 215 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
| 216 storage_layer_->SavePersistentUnreadList(unread_); | |
| 217 for (auto& observer : observers_) | 354 for (auto& observer : observers_) |
| 218 observer.ReadingListDidApplyChanges(this); | 355 observer.ReadingListDidApplyChanges(this); |
| 219 return; | 356 return; |
| 220 } | 357 } |
| 221 | 358 |
| 222 result = std::find(read_.begin(), read_.end(), entry); | 359 result = std::find(read_->begin(), read_->end(), entry); |
| 223 if (result != read_.end()) { | 360 if (result != read_->end()) { |
| 224 for (auto& observer : observers_) { | 361 for (auto& observer : observers_) |
| 225 observer.ReadingListWillUpdateReadEntry( | 362 observer.ReadingListWillUpdateReadEntry( |
| 226 this, std::distance(read_.begin(), result)); | 363 this, std::distance(read_->begin(), result)); |
| 364 result->SetTitle(title); |
| 365 if (storage_layer_) { |
| 366 storage_layer_->SaveEntry(*result, true); |
| 227 } | 367 } |
| 228 result->SetTitle(title); | |
| 229 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
| 230 storage_layer_->SavePersistentReadList(read_); | |
| 231 for (auto& observer : observers_) | 368 for (auto& observer : observers_) |
| 232 observer.ReadingListDidApplyChanges(this); | 369 observer.ReadingListDidApplyChanges(this); |
| 233 return; | 370 return; |
| 234 } | 371 } |
| 235 } | 372 } |
| 236 | 373 |
| 237 void ReadingListModelImpl::SetEntryDistilledPath( | 374 void ReadingListModelImpl::SetEntryDistilledPath( |
| 238 const GURL& url, | 375 const GURL& url, |
| 239 const base::FilePath& distilled_path) { | 376 const base::FilePath& distilled_path) { |
| 377 DCHECK(CalledOnValidThread()); |
| 240 DCHECK(loaded()); | 378 DCHECK(loaded()); |
| 241 const ReadingListEntry entry(url, std::string()); | 379 const ReadingListEntry entry(url, std::string()); |
| 242 | 380 |
| 243 auto result = std::find(unread_.begin(), unread_.end(), entry); | 381 auto result = std::find(unread_->begin(), unread_->end(), entry); |
| 244 if (result != unread_.end()) { | 382 if (result != unread_->end()) { |
| 245 for (auto& observer : observers_) { | 383 for (auto& observer : observers_) |
| 246 observer.ReadingListWillUpdateUnreadEntry( | 384 observer.ReadingListWillUpdateUnreadEntry( |
| 247 this, std::distance(unread_.begin(), result)); | 385 this, std::distance(unread_->begin(), result)); |
| 386 result->SetDistilledPath(distilled_path); |
| 387 if (storage_layer_) { |
| 388 storage_layer_->SaveEntry(*result, false); |
| 248 } | 389 } |
| 249 result->SetDistilledPath(distilled_path); | |
| 250 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
| 251 storage_layer_->SavePersistentUnreadList(unread_); | |
| 252 for (auto& observer : observers_) | 390 for (auto& observer : observers_) |
| 253 observer.ReadingListDidApplyChanges(this); | 391 observer.ReadingListDidApplyChanges(this); |
| 254 return; | 392 return; |
| 255 } | 393 } |
| 256 | 394 |
| 257 result = std::find(read_.begin(), read_.end(), entry); | 395 result = std::find(read_->begin(), read_->end(), entry); |
| 258 if (result != read_.end()) { | 396 if (result != read_->end()) { |
| 259 for (auto& observer : observers_) { | 397 for (auto& observer : observers_) |
| 260 observer.ReadingListWillUpdateReadEntry( | 398 observer.ReadingListWillUpdateReadEntry( |
| 261 this, std::distance(read_.begin(), result)); | 399 this, std::distance(read_->begin(), result)); |
| 400 result->SetDistilledPath(distilled_path); |
| 401 if (storage_layer_) { |
| 402 storage_layer_->SaveEntry(*result, true); |
| 262 } | 403 } |
| 263 result->SetDistilledPath(distilled_path); | |
| 264 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
| 265 storage_layer_->SavePersistentReadList(read_); | |
| 266 for (auto& observer : observers_) | 404 for (auto& observer : observers_) |
| 267 observer.ReadingListDidApplyChanges(this); | 405 observer.ReadingListDidApplyChanges(this); |
| 268 return; | 406 return; |
| 269 } | 407 } |
| 270 } | 408 } |
| 271 | 409 |
| 272 void ReadingListModelImpl::SetEntryDistilledState( | 410 void ReadingListModelImpl::SetEntryDistilledState( |
| 273 const GURL& url, | 411 const GURL& url, |
| 274 ReadingListEntry::DistillationState state) { | 412 ReadingListEntry::DistillationState state) { |
| 413 DCHECK(CalledOnValidThread()); |
| 275 DCHECK(loaded()); | 414 DCHECK(loaded()); |
| 276 const ReadingListEntry entry(url, std::string()); | 415 const ReadingListEntry entry(url, std::string()); |
| 277 | 416 |
| 278 auto result = std::find(unread_.begin(), unread_.end(), entry); | 417 auto result = std::find(unread_->begin(), unread_->end(), entry); |
| 279 if (result != unread_.end()) { | 418 if (result != unread_->end()) { |
| 280 for (auto& observer : observers_) { | 419 for (auto& observer : observers_) |
| 281 observer.ReadingListWillUpdateUnreadEntry( | 420 observer.ReadingListWillUpdateUnreadEntry( |
| 282 this, std::distance(unread_.begin(), result)); | 421 this, std::distance(unread_->begin(), result)); |
| 422 result->SetDistilledState(state); |
| 423 if (storage_layer_) { |
| 424 storage_layer_->SaveEntry(*result, false); |
| 283 } | 425 } |
| 284 result->SetDistilledState(state); | |
| 285 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
| 286 storage_layer_->SavePersistentUnreadList(unread_); | |
| 287 for (auto& observer : observers_) | 426 for (auto& observer : observers_) |
| 288 observer.ReadingListDidApplyChanges(this); | 427 observer.ReadingListDidApplyChanges(this); |
| 289 return; | 428 return; |
| 290 } | 429 } |
| 291 | 430 |
| 292 result = std::find(read_.begin(), read_.end(), entry); | 431 result = std::find(read_->begin(), read_->end(), entry); |
| 293 if (result != read_.end()) { | 432 if (result != read_->end()) { |
| 294 for (auto& observer : observers_) { | 433 for (auto& observer : observers_) |
| 295 observer.ReadingListWillUpdateReadEntry( | 434 observer.ReadingListWillUpdateReadEntry( |
| 296 this, std::distance(read_.begin(), result)); | 435 this, std::distance(read_->begin(), result)); |
| 436 result->SetDistilledState(state); |
| 437 if (storage_layer_) { |
| 438 storage_layer_->SaveEntry(*result, true); |
| 297 } | 439 } |
| 298 result->SetDistilledState(state); | |
| 299 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
| 300 storage_layer_->SavePersistentReadList(read_); | |
| 301 for (auto& observer : observers_) | 440 for (auto& observer : observers_) |
| 302 observer.ReadingListDidApplyChanges(this); | 441 observer.ReadingListDidApplyChanges(this); |
| 303 return; | 442 return; |
| 304 } | 443 } |
| 305 }; | 444 }; |
| 306 | 445 |
| 307 void ReadingListModelImpl::EndBatchUpdates() { | 446 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> |
| 308 ReadingListModel::EndBatchUpdates(); | 447 ReadingListModelImpl::CreateBatchToken() { |
| 309 if (IsPerformingBatchUpdates() || !storage_layer_) { | 448 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>( |
| 310 return; | 449 this); |
| 450 } |
| 451 |
| 452 ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| 453 ScopedReadingListBatchUpdate(ReadingListModelImpl* model) |
| 454 : ReadingListModel::ScopedReadingListBatchUpdate:: |
| 455 ScopedReadingListBatchUpdate(model) { |
| 456 if (model->StorageLayer()) { |
| 457 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); |
| 311 } | 458 } |
| 312 storage_layer_->SavePersistentUnreadList(unread_); | 459 } |
| 313 storage_layer_->SavePersistentReadList(read_); | 460 |
| 314 SetPersistentHasUnseen(has_unseen_); | 461 ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| 462 ~ScopedReadingListBatchUpdate() { |
| 463 storage_token_.reset(); |
| 464 } |
| 465 |
| 466 void ReadingListModelImpl::LeavingBatchUpdates() { |
| 467 DCHECK(CalledOnValidThread()); |
| 468 if (storage_layer_) { |
| 469 SetPersistentHasUnseen(has_unseen_); |
| 470 SortEntries(); |
| 471 } |
| 472 ReadingListModel::LeavingBatchUpdates(); |
| 473 } |
| 474 |
| 475 void ReadingListModelImpl::EnteringBatchUpdates() { |
| 476 DCHECK(CalledOnValidThread()); |
| 477 ReadingListModel::EnteringBatchUpdates(); |
| 315 } | 478 } |
| 316 | 479 |
| 317 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { | 480 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { |
| 481 DCHECK(CalledOnValidThread()); |
| 318 if (!pref_service_) { | 482 if (!pref_service_) { |
| 319 return; | 483 return; |
| 320 } | 484 } |
| 321 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, | 485 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, |
| 322 has_unseen); | 486 has_unseen); |
| 323 } | 487 } |
| 324 | 488 |
| 325 bool ReadingListModelImpl::GetPersistentHasUnseen() { | 489 bool ReadingListModelImpl::GetPersistentHasUnseen() { |
| 490 DCHECK(CalledOnValidThread()); |
| 326 if (!pref_service_) { | 491 if (!pref_service_) { |
| 327 return false; | 492 return false; |
| 328 } | 493 } |
| 329 return pref_service_->GetBoolean( | 494 return pref_service_->GetBoolean( |
| 330 reading_list::prefs::kReadingListHasUnseenEntries); | 495 reading_list::prefs::kReadingListHasUnseenEntries); |
| 331 } | 496 } |
| 497 |
| 498 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { |
| 499 DCHECK(loaded()); |
| 500 if (!storage_layer_) |
| 501 return nullptr; |
| 502 return storage_layer_->GetModelTypeSyncBridge(); |
| 503 } |
| 504 |
| 505 void ReadingListModelImpl::SortEntries() { |
| 506 DCHECK(CalledOnValidThread()); |
| 507 DCHECK(loaded()); |
| 508 std::sort(read_->begin(), read_->end(), |
| 509 ReadingListEntry::CompareEntryUpdateTime); |
| 510 std::sort(unread_->begin(), unread_->end(), |
| 511 ReadingListEntry::CompareEntryUpdateTime); |
| 512 } |
| 513 |
| 514 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() { |
| 515 return storage_layer_.get(); |
| 516 } |
| OLD | NEW |