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

Side by Side Diff: ios/chrome/browser/reading_list/reading_list_model_impl.cc

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

Powered by Google App Engine
This is Rietveld 408576698