| 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 "components/reading_list/core/reading_list_model_impl.h" | 5 #include "components/reading_list/core/reading_list_model_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/time/clock.h" | 11 #include "base/time/clock.h" |
| 12 #include "components/prefs/pref_service.h" | 12 #include "components/prefs/pref_service.h" |
| 13 #include "components/reading_list/core/reading_list_model_storage.h" | 13 #include "components/reading_list/core/reading_list_model_storage.h" |
| 14 #include "components/reading_list/core/reading_list_pref_names.h" | 14 #include "components/reading_list/core/reading_list_pref_names.h" |
| 15 #include "url/gurl.h" | 15 #include "url/gurl.h" |
| 16 | 16 |
| 17 ReadingListModelImpl::ReadingListModelImpl( | 17 ReadingListModelImpl::ReadingListModelImpl( |
| 18 std::unique_ptr<ReadingListModelStorage> storage, | 18 std::unique_ptr<ReadingListModelStorage> storage, |
| 19 PrefService* pref_service, | 19 PrefService* pref_service, |
| 20 std::unique_ptr<base::Clock> clock) | 20 std::unique_ptr<base::Clock> clock) |
| 21 : entries_(base::MakeUnique<ReadingListEntries>()), | 21 : entries_(base::MakeUnique<ReadingListEntries>()), |
| 22 unread_entry_count_(0), | 22 unread_entry_count_(0), |
| 23 read_entry_count_(0), | 23 read_entry_count_(0), |
| 24 unseen_entry_count_(0), | 24 unseen_entry_count_(0), |
| 25 clock_(std::move(clock)), | 25 clock_(std::move(clock)), |
| 26 pref_service_(pref_service), | 26 pref_service_(pref_service), |
| 27 has_unseen_(false), | 27 has_unseen_(false), |
| 28 loaded_(false), | 28 loaded_(false), |
| 29 weak_ptr_factory_(this) { | 29 weak_ptr_factory_(this) { |
| 30 DCHECK(CalledOnValidThread()); | 30 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 31 DCHECK(clock_); | 31 DCHECK(clock_); |
| 32 if (storage) { | 32 if (storage) { |
| 33 storage_layer_ = std::move(storage); | 33 storage_layer_ = std::move(storage); |
| 34 storage_layer_->SetReadingListModel(this, this, clock_.get()); | 34 storage_layer_->SetReadingListModel(this, this, clock_.get()); |
| 35 } else { | 35 } else { |
| 36 loaded_ = true; | 36 loaded_ = true; |
| 37 } | 37 } |
| 38 has_unseen_ = GetPersistentHasUnseen(); | 38 has_unseen_ = GetPersistentHasUnseen(); |
| 39 } | 39 } |
| 40 | 40 |
| 41 ReadingListModelImpl::~ReadingListModelImpl() {} | 41 ReadingListModelImpl::~ReadingListModelImpl() {} |
| 42 | 42 |
| 43 void ReadingListModelImpl::StoreLoaded( | 43 void ReadingListModelImpl::StoreLoaded( |
| 44 std::unique_ptr<ReadingListEntries> entries) { | 44 std::unique_ptr<ReadingListEntries> entries) { |
| 45 DCHECK(CalledOnValidThread()); | 45 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 46 DCHECK(entries); | 46 DCHECK(entries); |
| 47 entries_ = std::move(entries); | 47 entries_ = std::move(entries); |
| 48 for (auto& iterator : *entries_) { | 48 for (auto& iterator : *entries_) { |
| 49 UpdateEntryStateCountersOnEntryInsertion(iterator.second); | 49 UpdateEntryStateCountersOnEntryInsertion(iterator.second); |
| 50 } | 50 } |
| 51 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size()); | 51 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size()); |
| 52 loaded_ = true; | 52 loaded_ = true; |
| 53 for (auto& observer : observers_) | 53 for (auto& observer : observers_) |
| 54 observer.ReadingListModelLoaded(this); | 54 observer.ReadingListModelLoaded(this); |
| 55 } | 55 } |
| 56 | 56 |
| 57 void ReadingListModelImpl::Shutdown() { | 57 void ReadingListModelImpl::Shutdown() { |
| 58 DCHECK(CalledOnValidThread()); | 58 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 59 for (auto& observer : observers_) | 59 for (auto& observer : observers_) |
| 60 observer.ReadingListModelBeingShutdown(this); | 60 observer.ReadingListModelBeingShutdown(this); |
| 61 loaded_ = false; | 61 loaded_ = false; |
| 62 } | 62 } |
| 63 | 63 |
| 64 bool ReadingListModelImpl::loaded() const { | 64 bool ReadingListModelImpl::loaded() const { |
| 65 DCHECK(CalledOnValidThread()); | 65 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 66 return loaded_; | 66 return loaded_; |
| 67 } | 67 } |
| 68 | 68 |
| 69 size_t ReadingListModelImpl::size() const { | 69 size_t ReadingListModelImpl::size() const { |
| 70 DCHECK(CalledOnValidThread()); | 70 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 71 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size()); | 71 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size()); |
| 72 if (!loaded()) | 72 if (!loaded()) |
| 73 return 0; | 73 return 0; |
| 74 return entries_->size(); | 74 return entries_->size(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 size_t ReadingListModelImpl::unread_size() const { | 77 size_t ReadingListModelImpl::unread_size() const { |
| 78 DCHECK(CalledOnValidThread()); | 78 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 79 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size()); | 79 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size()); |
| 80 if (!loaded()) | 80 if (!loaded()) |
| 81 return 0; | 81 return 0; |
| 82 return unread_entry_count_; | 82 return unread_entry_count_; |
| 83 } | 83 } |
| 84 | 84 |
| 85 size_t ReadingListModelImpl::unseen_size() const { | 85 size_t ReadingListModelImpl::unseen_size() const { |
| 86 DCHECK(CalledOnValidThread()); | 86 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 87 if (!loaded()) | 87 if (!loaded()) |
| 88 return 0; | 88 return 0; |
| 89 return unseen_entry_count_; | 89 return unseen_entry_count_; |
| 90 } | 90 } |
| 91 | 91 |
| 92 void ReadingListModelImpl::SetUnseenFlag() { | 92 void ReadingListModelImpl::SetUnseenFlag() { |
| 93 if (!has_unseen_) { | 93 if (!has_unseen_) { |
| 94 has_unseen_ = true; | 94 has_unseen_ = true; |
| 95 if (!IsPerformingBatchUpdates()) { | 95 if (!IsPerformingBatchUpdates()) { |
| 96 SetPersistentHasUnseen(true); | 96 SetPersistentHasUnseen(true); |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 | 100 |
| 101 bool ReadingListModelImpl::GetLocalUnseenFlag() const { | 101 bool ReadingListModelImpl::GetLocalUnseenFlag() const { |
| 102 DCHECK(CalledOnValidThread()); | 102 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 103 if (!loaded()) | 103 if (!loaded()) |
| 104 return false; | 104 return false; |
| 105 // If there are currently no unseen entries, return false even if has_unseen_ | 105 // If there are currently no unseen entries, return false even if has_unseen_ |
| 106 // is true. | 106 // is true. |
| 107 // This is possible if the last unseen entry has be removed via sync. | 107 // This is possible if the last unseen entry has be removed via sync. |
| 108 return has_unseen_ && unseen_entry_count_; | 108 return has_unseen_ && unseen_entry_count_; |
| 109 } | 109 } |
| 110 | 110 |
| 111 void ReadingListModelImpl::ResetLocalUnseenFlag() { | 111 void ReadingListModelImpl::ResetLocalUnseenFlag() { |
| 112 DCHECK(CalledOnValidThread()); | 112 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 113 if (!loaded()) { | 113 if (!loaded()) { |
| 114 return; | 114 return; |
| 115 } | 115 } |
| 116 has_unseen_ = false; | 116 has_unseen_ = false; |
| 117 if (!IsPerformingBatchUpdates()) | 117 if (!IsPerformingBatchUpdates()) |
| 118 SetPersistentHasUnseen(false); | 118 SetPersistentHasUnseen(false); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void ReadingListModelImpl::MarkAllSeen() { | 121 void ReadingListModelImpl::MarkAllSeen() { |
| 122 DCHECK(CalledOnValidThread()); | 122 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 123 DCHECK(loaded()); | 123 DCHECK(loaded()); |
| 124 if (unseen_entry_count_ == 0) { | 124 if (unseen_entry_count_ == 0) { |
| 125 return; | 125 return; |
| 126 } | 126 } |
| 127 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> | 127 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> |
| 128 model_batch_updates = BeginBatchUpdates(); | 128 model_batch_updates = BeginBatchUpdates(); |
| 129 for (auto& iterator : *entries_) { | 129 for (auto& iterator : *entries_) { |
| 130 ReadingListEntry& entry = iterator.second; | 130 ReadingListEntry& entry = iterator.second; |
| 131 if (entry.HasBeenSeen()) { | 131 if (entry.HasBeenSeen()) { |
| 132 continue; | 132 continue; |
| 133 } | 133 } |
| 134 for (auto& observer : observers_) { | 134 for (auto& observer : observers_) { |
| 135 observer.ReadingListWillUpdateEntry(this, iterator.first); | 135 observer.ReadingListWillUpdateEntry(this, iterator.first); |
| 136 } | 136 } |
| 137 UpdateEntryStateCountersOnEntryRemoval(entry); | 137 UpdateEntryStateCountersOnEntryRemoval(entry); |
| 138 entry.SetRead(false, clock_->Now()); | 138 entry.SetRead(false, clock_->Now()); |
| 139 UpdateEntryStateCountersOnEntryInsertion(entry); | 139 UpdateEntryStateCountersOnEntryInsertion(entry); |
| 140 if (storage_layer_) { | 140 if (storage_layer_) { |
| 141 storage_layer_->SaveEntry(entry); | 141 storage_layer_->SaveEntry(entry); |
| 142 } | 142 } |
| 143 for (auto& observer : observers_) { | 143 for (auto& observer : observers_) { |
| 144 observer.ReadingListDidApplyChanges(this); | 144 observer.ReadingListDidApplyChanges(this); |
| 145 } | 145 } |
| 146 } | 146 } |
| 147 DCHECK(unseen_entry_count_ == 0); | 147 DCHECK(unseen_entry_count_ == 0); |
| 148 } | 148 } |
| 149 | 149 |
| 150 bool ReadingListModelImpl::DeleteAllEntries() { | 150 bool ReadingListModelImpl::DeleteAllEntries() { |
| 151 DCHECK(CalledOnValidThread()); | 151 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 152 if (!loaded()) { | 152 if (!loaded()) { |
| 153 return false; | 153 return false; |
| 154 } | 154 } |
| 155 auto scoped_model_batch_updates = BeginBatchUpdates(); | 155 auto scoped_model_batch_updates = BeginBatchUpdates(); |
| 156 for (const auto& url : Keys()) { | 156 for (const auto& url : Keys()) { |
| 157 RemoveEntryByURL(url); | 157 RemoveEntryByURL(url); |
| 158 } | 158 } |
| 159 return entries_->empty(); | 159 return entries_->empty(); |
| 160 } | 160 } |
| 161 | 161 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 186 const std::vector<GURL> ReadingListModelImpl::Keys() const { | 186 const std::vector<GURL> ReadingListModelImpl::Keys() const { |
| 187 std::vector<GURL> keys; | 187 std::vector<GURL> keys; |
| 188 for (const auto& iterator : *entries_) { | 188 for (const auto& iterator : *entries_) { |
| 189 keys.push_back(iterator.first); | 189 keys.push_back(iterator.first); |
| 190 } | 190 } |
| 191 return keys; | 191 return keys; |
| 192 } | 192 } |
| 193 | 193 |
| 194 const ReadingListEntry* ReadingListModelImpl::GetEntryByURL( | 194 const ReadingListEntry* ReadingListModelImpl::GetEntryByURL( |
| 195 const GURL& gurl) const { | 195 const GURL& gurl) const { |
| 196 DCHECK(CalledOnValidThread()); | 196 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 197 DCHECK(loaded()); | 197 DCHECK(loaded()); |
| 198 return GetMutableEntryFromURL(gurl); | 198 return GetMutableEntryFromURL(gurl); |
| 199 } | 199 } |
| 200 | 200 |
| 201 const ReadingListEntry* ReadingListModelImpl::GetFirstUnreadEntry( | 201 const ReadingListEntry* ReadingListModelImpl::GetFirstUnreadEntry( |
| 202 bool distilled) const { | 202 bool distilled) const { |
| 203 DCHECK(CalledOnValidThread()); | 203 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 204 DCHECK(loaded()); | 204 DCHECK(loaded()); |
| 205 if (unread_entry_count_ == 0) { | 205 if (unread_entry_count_ == 0) { |
| 206 return nullptr; | 206 return nullptr; |
| 207 } | 207 } |
| 208 int64_t update_time_all = 0; | 208 int64_t update_time_all = 0; |
| 209 const ReadingListEntry* first_entry_all = nullptr; | 209 const ReadingListEntry* first_entry_all = nullptr; |
| 210 int64_t update_time_distilled = 0; | 210 int64_t update_time_distilled = 0; |
| 211 const ReadingListEntry* first_entry_distilled = nullptr; | 211 const ReadingListEntry* first_entry_distilled = nullptr; |
| 212 for (auto& iterator : *entries_) { | 212 for (auto& iterator : *entries_) { |
| 213 ReadingListEntry& entry = iterator.second; | 213 ReadingListEntry& entry = iterator.second; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 227 DCHECK(first_entry_all); | 227 DCHECK(first_entry_all); |
| 228 DCHECK_GT(update_time_all, 0); | 228 DCHECK_GT(update_time_all, 0); |
| 229 if (distilled && first_entry_distilled) { | 229 if (distilled && first_entry_distilled) { |
| 230 return first_entry_distilled; | 230 return first_entry_distilled; |
| 231 } | 231 } |
| 232 return first_entry_all; | 232 return first_entry_all; |
| 233 } | 233 } |
| 234 | 234 |
| 235 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( | 235 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( |
| 236 const GURL& url) const { | 236 const GURL& url) const { |
| 237 DCHECK(CalledOnValidThread()); | 237 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 238 DCHECK(loaded()); | 238 DCHECK(loaded()); |
| 239 auto iterator = entries_->find(url); | 239 auto iterator = entries_->find(url); |
| 240 if (iterator == entries_->end()) { | 240 if (iterator == entries_->end()) { |
| 241 return nullptr; | 241 return nullptr; |
| 242 } | 242 } |
| 243 return &(iterator->second); | 243 return &(iterator->second); |
| 244 } | 244 } |
| 245 | 245 |
| 246 void ReadingListModelImpl::SyncAddEntry( | 246 void ReadingListModelImpl::SyncAddEntry( |
| 247 std::unique_ptr<ReadingListEntry> entry) { | 247 std::unique_ptr<ReadingListEntry> entry) { |
| 248 DCHECK(CalledOnValidThread()); | 248 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 249 DCHECK(loaded()); | 249 DCHECK(loaded()); |
| 250 // entry must not already exist. | 250 // entry must not already exist. |
| 251 DCHECK(GetMutableEntryFromURL(entry->URL()) == nullptr); | 251 DCHECK(GetMutableEntryFromURL(entry->URL()) == nullptr); |
| 252 for (auto& observer : observers_) | 252 for (auto& observer : observers_) |
| 253 observer.ReadingListWillAddEntry(this, *entry); | 253 observer.ReadingListWillAddEntry(this, *entry); |
| 254 UpdateEntryStateCountersOnEntryInsertion(*entry); | 254 UpdateEntryStateCountersOnEntryInsertion(*entry); |
| 255 if (!entry->HasBeenSeen()) { | 255 if (!entry->HasBeenSeen()) { |
| 256 SetUnseenFlag(); | 256 SetUnseenFlag(); |
| 257 } | 257 } |
| 258 GURL url = entry->URL(); | 258 GURL url = entry->URL(); |
| 259 entries_->insert(std::make_pair(url, std::move(*entry))); | 259 entries_->insert(std::make_pair(url, std::move(*entry))); |
| 260 for (auto& observer : observers_) { | 260 for (auto& observer : observers_) { |
| 261 observer.ReadingListDidAddEntry(this, url, reading_list::ADDED_VIA_SYNC); | 261 observer.ReadingListDidAddEntry(this, url, reading_list::ADDED_VIA_SYNC); |
| 262 observer.ReadingListDidApplyChanges(this); | 262 observer.ReadingListDidApplyChanges(this); |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 | 265 |
| 266 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry( | 266 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry( |
| 267 std::unique_ptr<ReadingListEntry> entry) { | 267 std::unique_ptr<ReadingListEntry> entry) { |
| 268 DCHECK(CalledOnValidThread()); | 268 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 269 DCHECK(loaded()); | 269 DCHECK(loaded()); |
| 270 ReadingListEntry* existing_entry = GetMutableEntryFromURL(entry->URL()); | 270 ReadingListEntry* existing_entry = GetMutableEntryFromURL(entry->URL()); |
| 271 DCHECK(existing_entry); | 271 DCHECK(existing_entry); |
| 272 GURL url = entry->URL(); | 272 GURL url = entry->URL(); |
| 273 | 273 |
| 274 for (auto& observer : observers_) | 274 for (auto& observer : observers_) |
| 275 observer.ReadingListWillMoveEntry(this, url); | 275 observer.ReadingListWillMoveEntry(this, url); |
| 276 | 276 |
| 277 bool was_seen = existing_entry->HasBeenSeen(); | 277 bool was_seen = existing_entry->HasBeenSeen(); |
| 278 UpdateEntryStateCountersOnEntryRemoval(*existing_entry); | 278 UpdateEntryStateCountersOnEntryRemoval(*existing_entry); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 294 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) { | 294 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) { |
| 295 RemoveEntryByURLImpl(url, true); | 295 RemoveEntryByURLImpl(url, true); |
| 296 } | 296 } |
| 297 | 297 |
| 298 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { | 298 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { |
| 299 RemoveEntryByURLImpl(url, false); | 299 RemoveEntryByURLImpl(url, false); |
| 300 } | 300 } |
| 301 | 301 |
| 302 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, | 302 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, |
| 303 bool from_sync) { | 303 bool from_sync) { |
| 304 DCHECK(CalledOnValidThread()); | 304 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 305 DCHECK(loaded()); | 305 DCHECK(loaded()); |
| 306 const ReadingListEntry* entry = GetEntryByURL(url); | 306 const ReadingListEntry* entry = GetEntryByURL(url); |
| 307 if (!entry) | 307 if (!entry) |
| 308 return; | 308 return; |
| 309 | 309 |
| 310 for (auto& observer : observers_) | 310 for (auto& observer : observers_) |
| 311 observer.ReadingListWillRemoveEntry(this, url); | 311 observer.ReadingListWillRemoveEntry(this, url); |
| 312 | 312 |
| 313 if (storage_layer_ && !from_sync) { | 313 if (storage_layer_ && !from_sync) { |
| 314 storage_layer_->RemoveEntry(*entry); | 314 storage_layer_->RemoveEntry(*entry); |
| 315 } | 315 } |
| 316 UpdateEntryStateCountersOnEntryRemoval(*entry); | 316 UpdateEntryStateCountersOnEntryRemoval(*entry); |
| 317 | 317 |
| 318 entries_->erase(url); | 318 entries_->erase(url); |
| 319 for (auto& observer : observers_) | 319 for (auto& observer : observers_) |
| 320 observer.ReadingListDidApplyChanges(this); | 320 observer.ReadingListDidApplyChanges(this); |
| 321 } | 321 } |
| 322 | 322 |
| 323 const ReadingListEntry& ReadingListModelImpl::AddEntry( | 323 const ReadingListEntry& ReadingListModelImpl::AddEntry( |
| 324 const GURL& url, | 324 const GURL& url, |
| 325 const std::string& title, | 325 const std::string& title, |
| 326 reading_list::EntrySource source) { | 326 reading_list::EntrySource source) { |
| 327 DCHECK(CalledOnValidThread()); | 327 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 328 DCHECK(loaded()); | 328 DCHECK(loaded()); |
| 329 DCHECK(url.SchemeIsHTTPOrHTTPS()); | 329 DCHECK(url.SchemeIsHTTPOrHTTPS()); |
| 330 RemoveEntryByURL(url); | 330 RemoveEntryByURL(url); |
| 331 | 331 |
| 332 std::string trimmed_title = base::CollapseWhitespaceASCII(title, false); | 332 std::string trimmed_title = base::CollapseWhitespaceASCII(title, false); |
| 333 | 333 |
| 334 ReadingListEntry entry(url, trimmed_title, clock_->Now()); | 334 ReadingListEntry entry(url, trimmed_title, clock_->Now()); |
| 335 for (auto& observer : observers_) | 335 for (auto& observer : observers_) |
| 336 observer.ReadingListWillAddEntry(this, entry); | 336 observer.ReadingListWillAddEntry(this, entry); |
| 337 UpdateEntryStateCountersOnEntryInsertion(entry); | 337 UpdateEntryStateCountersOnEntryInsertion(entry); |
| 338 SetUnseenFlag(); | 338 SetUnseenFlag(); |
| 339 entries_->insert(std::make_pair(url, std::move(entry))); | 339 entries_->insert(std::make_pair(url, std::move(entry))); |
| 340 | 340 |
| 341 if (storage_layer_) { | 341 if (storage_layer_) { |
| 342 storage_layer_->SaveEntry(*GetEntryByURL(url)); | 342 storage_layer_->SaveEntry(*GetEntryByURL(url)); |
| 343 } | 343 } |
| 344 | 344 |
| 345 for (auto& observer : observers_) { | 345 for (auto& observer : observers_) { |
| 346 observer.ReadingListDidAddEntry(this, url, source); | 346 observer.ReadingListDidAddEntry(this, url, source); |
| 347 observer.ReadingListDidApplyChanges(this); | 347 observer.ReadingListDidApplyChanges(this); |
| 348 } | 348 } |
| 349 | 349 |
| 350 return entries_->at(url); | 350 return entries_->at(url); |
| 351 } | 351 } |
| 352 | 352 |
| 353 void ReadingListModelImpl::SetReadStatus(const GURL& url, bool read) { | 353 void ReadingListModelImpl::SetReadStatus(const GURL& url, bool read) { |
| 354 DCHECK(CalledOnValidThread()); | 354 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 355 DCHECK(loaded()); | 355 DCHECK(loaded()); |
| 356 auto iterator = entries_->find(url); | 356 auto iterator = entries_->find(url); |
| 357 if (iterator == entries_->end()) { | 357 if (iterator == entries_->end()) { |
| 358 return; | 358 return; |
| 359 } | 359 } |
| 360 ReadingListEntry& entry = iterator->second; | 360 ReadingListEntry& entry = iterator->second; |
| 361 if (entry.IsRead() == read) { | 361 if (entry.IsRead() == read) { |
| 362 return; | 362 return; |
| 363 } | 363 } |
| 364 for (ReadingListModelObserver& observer : observers_) { | 364 for (ReadingListModelObserver& observer : observers_) { |
| 365 observer.ReadingListWillMoveEntry(this, url); | 365 observer.ReadingListWillMoveEntry(this, url); |
| 366 } | 366 } |
| 367 UpdateEntryStateCountersOnEntryRemoval(entry); | 367 UpdateEntryStateCountersOnEntryRemoval(entry); |
| 368 entry.SetRead(read, clock_->Now()); | 368 entry.SetRead(read, clock_->Now()); |
| 369 entry.MarkEntryUpdated(clock_->Now()); | 369 entry.MarkEntryUpdated(clock_->Now()); |
| 370 UpdateEntryStateCountersOnEntryInsertion(entry); | 370 UpdateEntryStateCountersOnEntryInsertion(entry); |
| 371 | 371 |
| 372 if (storage_layer_) { | 372 if (storage_layer_) { |
| 373 storage_layer_->SaveEntry(entry); | 373 storage_layer_->SaveEntry(entry); |
| 374 } | 374 } |
| 375 for (ReadingListModelObserver& observer : observers_) { | 375 for (ReadingListModelObserver& observer : observers_) { |
| 376 observer.ReadingListDidMoveEntry(this, url); | 376 observer.ReadingListDidMoveEntry(this, url); |
| 377 observer.ReadingListDidApplyChanges(this); | 377 observer.ReadingListDidApplyChanges(this); |
| 378 } | 378 } |
| 379 } | 379 } |
| 380 | 380 |
| 381 void ReadingListModelImpl::SetEntryTitle(const GURL& url, | 381 void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
| 382 const std::string& title) { | 382 const std::string& title) { |
| 383 DCHECK(CalledOnValidThread()); | 383 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 384 DCHECK(loaded()); | 384 DCHECK(loaded()); |
| 385 auto iterator = entries_->find(url); | 385 auto iterator = entries_->find(url); |
| 386 if (iterator == entries_->end()) { | 386 if (iterator == entries_->end()) { |
| 387 return; | 387 return; |
| 388 } | 388 } |
| 389 ReadingListEntry& entry = iterator->second; | 389 ReadingListEntry& entry = iterator->second; |
| 390 std::string trimmed_title = base::CollapseWhitespaceASCII(title, false); | 390 std::string trimmed_title = base::CollapseWhitespaceASCII(title, false); |
| 391 if (entry.Title() == trimmed_title) { | 391 if (entry.Title() == trimmed_title) { |
| 392 return; | 392 return; |
| 393 } | 393 } |
| 394 | 394 |
| 395 for (ReadingListModelObserver& observer : observers_) { | 395 for (ReadingListModelObserver& observer : observers_) { |
| 396 observer.ReadingListWillUpdateEntry(this, url); | 396 observer.ReadingListWillUpdateEntry(this, url); |
| 397 } | 397 } |
| 398 entry.SetTitle(trimmed_title, clock_->Now()); | 398 entry.SetTitle(trimmed_title, clock_->Now()); |
| 399 if (storage_layer_) { | 399 if (storage_layer_) { |
| 400 storage_layer_->SaveEntry(entry); | 400 storage_layer_->SaveEntry(entry); |
| 401 } | 401 } |
| 402 for (ReadingListModelObserver& observer : observers_) { | 402 for (ReadingListModelObserver& observer : observers_) { |
| 403 observer.ReadingListDidApplyChanges(this); | 403 observer.ReadingListDidApplyChanges(this); |
| 404 } | 404 } |
| 405 } | 405 } |
| 406 | 406 |
| 407 void ReadingListModelImpl::SetEntryDistilledInfo( | 407 void ReadingListModelImpl::SetEntryDistilledInfo( |
| 408 const GURL& url, | 408 const GURL& url, |
| 409 const base::FilePath& distilled_path, | 409 const base::FilePath& distilled_path, |
| 410 const GURL& distilled_url, | 410 const GURL& distilled_url, |
| 411 int64_t distillation_size, | 411 int64_t distillation_size, |
| 412 const base::Time& distillation_date) { | 412 const base::Time& distillation_date) { |
| 413 DCHECK(CalledOnValidThread()); | 413 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 414 DCHECK(loaded()); | 414 DCHECK(loaded()); |
| 415 auto iterator = entries_->find(url); | 415 auto iterator = entries_->find(url); |
| 416 if (iterator == entries_->end()) { | 416 if (iterator == entries_->end()) { |
| 417 return; | 417 return; |
| 418 } | 418 } |
| 419 ReadingListEntry& entry = iterator->second; | 419 ReadingListEntry& entry = iterator->second; |
| 420 if (entry.DistilledState() == ReadingListEntry::PROCESSED && | 420 if (entry.DistilledState() == ReadingListEntry::PROCESSED && |
| 421 entry.DistilledPath() == distilled_path) { | 421 entry.DistilledPath() == distilled_path) { |
| 422 return; | 422 return; |
| 423 } | 423 } |
| 424 | 424 |
| 425 for (ReadingListModelObserver& observer : observers_) { | 425 for (ReadingListModelObserver& observer : observers_) { |
| 426 observer.ReadingListWillUpdateEntry(this, url); | 426 observer.ReadingListWillUpdateEntry(this, url); |
| 427 } | 427 } |
| 428 entry.SetDistilledInfo(distilled_path, distilled_url, distillation_size, | 428 entry.SetDistilledInfo(distilled_path, distilled_url, distillation_size, |
| 429 distillation_date); | 429 distillation_date); |
| 430 if (storage_layer_) { | 430 if (storage_layer_) { |
| 431 storage_layer_->SaveEntry(entry); | 431 storage_layer_->SaveEntry(entry); |
| 432 } | 432 } |
| 433 for (ReadingListModelObserver& observer : observers_) { | 433 for (ReadingListModelObserver& observer : observers_) { |
| 434 observer.ReadingListDidApplyChanges(this); | 434 observer.ReadingListDidApplyChanges(this); |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 | 437 |
| 438 void ReadingListModelImpl::SetEntryDistilledState( | 438 void ReadingListModelImpl::SetEntryDistilledState( |
| 439 const GURL& url, | 439 const GURL& url, |
| 440 ReadingListEntry::DistillationState state) { | 440 ReadingListEntry::DistillationState state) { |
| 441 DCHECK(CalledOnValidThread()); | 441 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 442 DCHECK(loaded()); | 442 DCHECK(loaded()); |
| 443 auto iterator = entries_->find(url); | 443 auto iterator = entries_->find(url); |
| 444 if (iterator == entries_->end()) { | 444 if (iterator == entries_->end()) { |
| 445 return; | 445 return; |
| 446 } | 446 } |
| 447 ReadingListEntry& entry = iterator->second; | 447 ReadingListEntry& entry = iterator->second; |
| 448 if (entry.DistilledState() == state) { | 448 if (entry.DistilledState() == state) { |
| 449 return; | 449 return; |
| 450 } | 450 } |
| 451 | 451 |
| 452 for (ReadingListModelObserver& observer : observers_) { | 452 for (ReadingListModelObserver& observer : observers_) { |
| 453 observer.ReadingListWillUpdateEntry(this, url); | 453 observer.ReadingListWillUpdateEntry(this, url); |
| 454 } | 454 } |
| 455 entry.SetDistilledState(state); | 455 entry.SetDistilledState(state); |
| 456 if (storage_layer_) { | 456 if (storage_layer_) { |
| 457 storage_layer_->SaveEntry(entry); | 457 storage_layer_->SaveEntry(entry); |
| 458 } | 458 } |
| 459 for (ReadingListModelObserver& observer : observers_) { | 459 for (ReadingListModelObserver& observer : observers_) { |
| 460 observer.ReadingListDidApplyChanges(this); | 460 observer.ReadingListDidApplyChanges(this); |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 void ReadingListModelImpl::SetContentSuggestionsExtra( | 464 void ReadingListModelImpl::SetContentSuggestionsExtra( |
| 465 const GURL& url, | 465 const GURL& url, |
| 466 const reading_list::ContentSuggestionsExtra& extra) { | 466 const reading_list::ContentSuggestionsExtra& extra) { |
| 467 DCHECK(CalledOnValidThread()); | 467 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 468 DCHECK(loaded()); | 468 DCHECK(loaded()); |
| 469 ReadingListEntry* entry = GetMutableEntryFromURL(url); | 469 ReadingListEntry* entry = GetMutableEntryFromURL(url); |
| 470 if (!entry) { | 470 if (!entry) { |
| 471 return; | 471 return; |
| 472 } | 472 } |
| 473 | 473 |
| 474 for (ReadingListModelObserver& observer : observers_) { | 474 for (ReadingListModelObserver& observer : observers_) { |
| 475 observer.ReadingListWillUpdateEntry(this, url); | 475 observer.ReadingListWillUpdateEntry(this, url); |
| 476 } | 476 } |
| 477 entry->SetContentSuggestionsExtra(extra); | 477 entry->SetContentSuggestionsExtra(extra); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 497 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); | 497 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); |
| 498 } | 498 } |
| 499 } | 499 } |
| 500 | 500 |
| 501 ReadingListModelImpl::ScopedReadingListBatchUpdate:: | 501 ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| 502 ~ScopedReadingListBatchUpdate() { | 502 ~ScopedReadingListBatchUpdate() { |
| 503 storage_token_.reset(); | 503 storage_token_.reset(); |
| 504 } | 504 } |
| 505 | 505 |
| 506 void ReadingListModelImpl::LeavingBatchUpdates() { | 506 void ReadingListModelImpl::LeavingBatchUpdates() { |
| 507 DCHECK(CalledOnValidThread()); | 507 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 508 if (storage_layer_) { | 508 if (storage_layer_) { |
| 509 SetPersistentHasUnseen(has_unseen_); | 509 SetPersistentHasUnseen(has_unseen_); |
| 510 } | 510 } |
| 511 ReadingListModel::LeavingBatchUpdates(); | 511 ReadingListModel::LeavingBatchUpdates(); |
| 512 } | 512 } |
| 513 | 513 |
| 514 void ReadingListModelImpl::EnteringBatchUpdates() { | 514 void ReadingListModelImpl::EnteringBatchUpdates() { |
| 515 DCHECK(CalledOnValidThread()); | 515 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 516 ReadingListModel::EnteringBatchUpdates(); | 516 ReadingListModel::EnteringBatchUpdates(); |
| 517 } | 517 } |
| 518 | 518 |
| 519 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { | 519 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { |
| 520 DCHECK(CalledOnValidThread()); | 520 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 521 if (!pref_service_) { | 521 if (!pref_service_) { |
| 522 return; | 522 return; |
| 523 } | 523 } |
| 524 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, | 524 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, |
| 525 has_unseen); | 525 has_unseen); |
| 526 } | 526 } |
| 527 | 527 |
| 528 bool ReadingListModelImpl::GetPersistentHasUnseen() { | 528 bool ReadingListModelImpl::GetPersistentHasUnseen() { |
| 529 DCHECK(CalledOnValidThread()); | 529 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 530 if (!pref_service_) { | 530 if (!pref_service_) { |
| 531 return false; | 531 return false; |
| 532 } | 532 } |
| 533 return pref_service_->GetBoolean( | 533 return pref_service_->GetBoolean( |
| 534 reading_list::prefs::kReadingListHasUnseenEntries); | 534 reading_list::prefs::kReadingListHasUnseenEntries); |
| 535 } | 535 } |
| 536 | 536 |
| 537 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { | 537 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { |
| 538 if (!storage_layer_) | 538 if (!storage_layer_) |
| 539 return nullptr; | 539 return nullptr; |
| 540 return storage_layer_.get(); | 540 return storage_layer_.get(); |
| 541 } | 541 } |
| 542 | 542 |
| 543 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() { | 543 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() { |
| 544 return storage_layer_.get(); | 544 return storage_layer_.get(); |
| 545 } | 545 } |
| OLD | NEW |