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

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

Powered by Google App Engine
This is Rietveld 408576698