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

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

Powered by Google App Engine
This is Rietveld 408576698