Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: components/reading_list/reading_list_model_impl.cc

Issue 2511723002: Enable RL sync by default on iOS (Closed)
Patch Set: rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/reading_list/reading_list_model_impl.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ptr_util.h"
10 #include "base/strings/string_util.h"
11 #include "components/prefs/pref_service.h"
12 #include "components/reading_list/reading_list_model_storage.h"
13 #include "components/reading_list/reading_list_pref_names.h"
14 #include "url/gurl.h"
15
16 ReadingListModelImpl::ReadingListModelImpl()
17 : ReadingListModelImpl(nullptr, nullptr) {}
18
19 ReadingListModelImpl::ReadingListModelImpl(
20 std::unique_ptr<ReadingListModelStorage> storage,
21 PrefService* pref_service)
22 : pref_service_(pref_service),
23 has_unseen_(false),
24 loaded_(false),
25 weak_ptr_factory_(this) {
26 DCHECK(CalledOnValidThread());
27 if (storage) {
28 storage_layer_ = std::move(storage);
29 storage_layer_->SetReadingListModel(this, this);
30 } else {
31 loaded_ = true;
32 read_ = base::MakeUnique<ReadingListEntries>();
33 unread_ = base::MakeUnique<ReadingListEntries>();
34 }
35 has_unseen_ = GetPersistentHasUnseen();
36 }
37
38 ReadingListModelImpl::~ReadingListModelImpl() {}
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
52 void ReadingListModelImpl::Shutdown() {
53 DCHECK(CalledOnValidThread());
54 for (auto& observer : observers_)
55 observer.ReadingListModelBeingDeleted(this);
56 loaded_ = false;
57 }
58
59 bool ReadingListModelImpl::loaded() const {
60 DCHECK(CalledOnValidThread());
61 return loaded_;
62 }
63
64 size_t ReadingListModelImpl::unread_size() const {
65 DCHECK(CalledOnValidThread());
66 if (!loaded())
67 return 0;
68 return unread_->size();
69 }
70
71 size_t ReadingListModelImpl::read_size() const {
72 DCHECK(CalledOnValidThread());
73 if (!loaded())
74 return 0;
75 return read_->size();
76 }
77
78 bool ReadingListModelImpl::HasUnseenEntries() const {
79 DCHECK(CalledOnValidThread());
80 if (!loaded())
81 return false;
82 return unread_size() && has_unseen_;
83 }
84
85 void ReadingListModelImpl::ResetUnseenEntries() {
86 DCHECK(CalledOnValidThread());
87 DCHECK(loaded());
88 has_unseen_ = false;
89 if (!IsPerformingBatchUpdates())
90 SetPersistentHasUnseen(false);
91 }
92
93 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex(
94 size_t index) const {
95 DCHECK(CalledOnValidThread());
96 DCHECK(loaded());
97 return unread_->at(index);
98 }
99
100 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex(
101 size_t index) const {
102 DCHECK(CalledOnValidThread());
103 DCHECK(loaded());
104 return read_->at(index);
105 }
106
107 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL(
108 const GURL& gurl,
109 bool* read) const {
110 DCHECK(CalledOnValidThread());
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;
121 ReadingListEntry entry(gurl, std::string());
122 auto it = std::find(read_->begin(), read_->end(), entry);
123 is_read = true;
124 if (it == read_->end()) {
125 it = std::find(unread_->begin(), unread_->end(), entry);
126 is_read = false;
127 if (it == unread_->end())
128 return nullptr;
129 }
130 if (read) {
131 *read = is_read;
132 }
133 return &(*it);
134 }
135
136 bool ReadingListModelImpl::CallbackEntryURL(
137 const GURL& url,
138 base::Callback<void(const ReadingListEntry&)> callback) const {
139 DCHECK(CalledOnValidThread());
140 DCHECK(loaded());
141 const ReadingListEntry* entry = GetMutableEntryFromURL(url, nullptr);
142 if (entry) {
143 callback.Run(*entry);
144 return true;
145 }
146 return false;
147 }
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
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());
228 DCHECK(loaded());
229 const ReadingListEntry entry(url, std::string());
230
231 auto result = std::find(unread_->begin(), unread_->end(), entry);
232 if (result != unread_->end()) {
233 for (auto& observer : observers_)
234 observer.ReadingListWillRemoveUnreadEntry(
235 this, std::distance(unread_->begin(), result));
236
237 if (storage_layer_ && !from_sync) {
238 storage_layer_->RemoveEntry(*result);
239 }
240 unread_->erase(result);
241
242 for (auto& observer : observers_)
243 observer.ReadingListDidApplyChanges(this);
244 return;
245 }
246
247 result = std::find(read_->begin(), read_->end(), entry);
248 if (result != read_->end()) {
249 for (auto& observer : observers_)
250 observer.ReadingListWillRemoveReadEntry(
251 this, std::distance(read_->begin(), result));
252 if (storage_layer_ && !from_sync) {
253 storage_layer_->RemoveEntry(*result);
254 }
255 read_->erase(result);
256
257 for (auto& observer : observers_)
258 observer.ReadingListDidApplyChanges(this);
259 return;
260 }
261 }
262
263 const ReadingListEntry& ReadingListModelImpl::AddEntry(
264 const GURL& url,
265 const std::string& title) {
266 DCHECK(CalledOnValidThread());
267 DCHECK(loaded());
268 RemoveEntryByURL(url);
269
270 std::string trimmedTitle(title);
271 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle);
272
273 ReadingListEntry entry(url, trimmedTitle);
274 for (auto& observer : observers_)
275 observer.ReadingListWillAddUnreadEntry(this, entry);
276 has_unseen_ = true;
277 SetPersistentHasUnseen(true);
278 if (storage_layer_) {
279 storage_layer_->SaveEntry(entry, false);
280 }
281 unread_->insert(unread_->begin(), std::move(entry));
282
283 for (auto& observer : observers_)
284 observer.ReadingListDidApplyChanges(this);
285 return *unread_->begin();
286 }
287
288 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) {
289 DCHECK(CalledOnValidThread());
290 DCHECK(loaded());
291 ReadingListEntry entry(url, std::string());
292 auto result = std::find(read_->begin(), read_->end(), entry);
293 if (result == read_->end())
294 return;
295
296 for (ReadingListModelObserver& observer : observers_) {
297 observer.ReadingListWillMoveEntry(
298 this, std::distance(read_->begin(), result), true);
299 }
300
301 result->MarkEntryUpdated();
302 if (storage_layer_) {
303 storage_layer_->SaveEntry(*result, false);
304 }
305
306 unread_->insert(unread_->begin(), std::move(*result));
307 read_->erase(result);
308
309 for (ReadingListModelObserver& observer : observers_) {
310 observer.ReadingListDidApplyChanges(this);
311 }
312 }
313
314 void ReadingListModelImpl::MarkReadByURL(const GURL& url) {
315 DCHECK(CalledOnValidThread());
316 DCHECK(loaded());
317 ReadingListEntry entry(url, std::string());
318 auto result = std::find(unread_->begin(), unread_->end(), entry);
319 if (result == unread_->end())
320 return;
321
322 for (auto& observer : observers_)
323 observer.ReadingListWillMoveEntry(
324 this, std::distance(unread_->begin(), result), false);
325
326 result->MarkEntryUpdated();
327 if (storage_layer_) {
328 storage_layer_->SaveEntry(*result, true);
329 }
330
331 read_->insert(read_->begin(), std::move(*result));
332 unread_->erase(result);
333
334 for (auto& observer : observers_)
335 observer.ReadingListDidApplyChanges(this);
336 }
337
338 void ReadingListModelImpl::SetEntryTitle(const GURL& url,
339 const std::string& title) {
340 DCHECK(CalledOnValidThread());
341 DCHECK(loaded());
342 const ReadingListEntry entry(url, std::string());
343
344 auto result = std::find(unread_->begin(), unread_->end(), entry);
345 if (result != unread_->end()) {
346 for (auto& observer : observers_)
347 observer.ReadingListWillUpdateUnreadEntry(
348 this, std::distance(unread_->begin(), result));
349 result->SetTitle(title);
350
351 if (storage_layer_) {
352 storage_layer_->SaveEntry(*result, false);
353 }
354 for (auto& observer : observers_)
355 observer.ReadingListDidApplyChanges(this);
356 return;
357 }
358
359 result = std::find(read_->begin(), read_->end(), entry);
360 if (result != read_->end()) {
361 for (auto& observer : observers_)
362 observer.ReadingListWillUpdateReadEntry(
363 this, std::distance(read_->begin(), result));
364 result->SetTitle(title);
365 if (storage_layer_) {
366 storage_layer_->SaveEntry(*result, true);
367 }
368 for (auto& observer : observers_)
369 observer.ReadingListDidApplyChanges(this);
370 return;
371 }
372 }
373
374 void ReadingListModelImpl::SetEntryDistilledPath(
375 const GURL& url,
376 const base::FilePath& distilled_path) {
377 DCHECK(CalledOnValidThread());
378 DCHECK(loaded());
379 const ReadingListEntry entry(url, std::string());
380
381 auto result = std::find(unread_->begin(), unread_->end(), entry);
382 if (result != unread_->end()) {
383 for (auto& observer : observers_)
384 observer.ReadingListWillUpdateUnreadEntry(
385 this, std::distance(unread_->begin(), result));
386 result->SetDistilledPath(distilled_path);
387 if (storage_layer_) {
388 storage_layer_->SaveEntry(*result, false);
389 }
390 for (auto& observer : observers_)
391 observer.ReadingListDidApplyChanges(this);
392 return;
393 }
394
395 result = std::find(read_->begin(), read_->end(), entry);
396 if (result != read_->end()) {
397 for (auto& observer : observers_)
398 observer.ReadingListWillUpdateReadEntry(
399 this, std::distance(read_->begin(), result));
400 result->SetDistilledPath(distilled_path);
401 if (storage_layer_) {
402 storage_layer_->SaveEntry(*result, true);
403 }
404 for (auto& observer : observers_)
405 observer.ReadingListDidApplyChanges(this);
406 return;
407 }
408 }
409
410 void ReadingListModelImpl::SetEntryDistilledState(
411 const GURL& url,
412 ReadingListEntry::DistillationState state) {
413 DCHECK(CalledOnValidThread());
414 DCHECK(loaded());
415 const ReadingListEntry entry(url, std::string());
416
417 auto result = std::find(unread_->begin(), unread_->end(), entry);
418 if (result != unread_->end()) {
419 for (auto& observer : observers_)
420 observer.ReadingListWillUpdateUnreadEntry(
421 this, std::distance(unread_->begin(), result));
422 result->SetDistilledState(state);
423 if (storage_layer_) {
424 storage_layer_->SaveEntry(*result, false);
425 }
426 for (auto& observer : observers_)
427 observer.ReadingListDidApplyChanges(this);
428 return;
429 }
430
431 result = std::find(read_->begin(), read_->end(), entry);
432 if (result != read_->end()) {
433 for (auto& observer : observers_)
434 observer.ReadingListWillUpdateReadEntry(
435 this, std::distance(read_->begin(), result));
436 result->SetDistilledState(state);
437 if (storage_layer_) {
438 storage_layer_->SaveEntry(*result, true);
439 }
440 for (auto& observer : observers_)
441 observer.ReadingListDidApplyChanges(this);
442 return;
443 }
444 };
445
446 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate>
447 ReadingListModelImpl::CreateBatchToken() {
448 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>(
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();
458 }
459 }
460
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();
478 }
479
480 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) {
481 DCHECK(CalledOnValidThread());
482 if (!pref_service_) {
483 return;
484 }
485 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries,
486 has_unseen);
487 }
488
489 bool ReadingListModelImpl::GetPersistentHasUnseen() {
490 DCHECK(CalledOnValidThread());
491 if (!pref_service_) {
492 return false;
493 }
494 return pref_service_->GetBoolean(
495 reading_list::prefs::kReadingListHasUnseenEntries);
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 }
OLDNEW
« no previous file with comments | « components/reading_list/reading_list_model_impl.h ('k') | components/reading_list/reading_list_model_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698