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 |