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

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: experimental_flags 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(NULL, NULL) {}
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_CURRENTLY_ON(web::WebThread::UI);
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);
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_ = LoadPersistentHasUnseen();
22 } 36 }
23 ReadingListModelImpl::~ReadingListModelImpl() {} 37 ReadingListModelImpl::~ReadingListModelImpl() {}
24 38
39 void ReadingListModelImpl::ModelLoaded(
40 std::unique_ptr<ReadingListEntries> unread,
41 std::unique_ptr<ReadingListEntries> read) {
42 DCHECK_CURRENTLY_ON(web::WebThread::UI);
43 read_ = std::move(read);
44 unread_ = std::move(unread);
45 SortEntries();
46 loaded_ = true;
47 for (auto& observer : observers_)
48 observer.ReadingListModelLoaded(this);
49 }
50
25 void ReadingListModelImpl::Shutdown() { 51 void ReadingListModelImpl::Shutdown() {
52 DCHECK_CURRENTLY_ON(web::WebThread::UI);
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_CURRENTLY_ON(web::WebThread::UI);
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_CURRENTLY_ON(web::WebThread::UI);
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_CURRENTLY_ON(web::WebThread::UI);
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_CURRENTLY_ON(web::WebThread::UI);
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() {
51 DCHECK(loaded()); 85 DCHECK(loaded());
52 hasUnseen_ = false; 86 has_unseen_ = false;
53 if (storageLayer_ && !IsPerformingBatchUpdates()) 87 if (!IsPerformingBatchUpdates())
54 storageLayer_->SavePersistentHasUnseen(false); 88 SavePersistentHasUnseen(false);
55 } 89 }
56 90
57 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( 91 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex(
58 size_t index) const { 92 size_t index) const {
93 DCHECK_CURRENTLY_ON(web::WebThread::UI);
59 DCHECK(loaded()); 94 DCHECK(loaded());
60 return unread_[index]; 95 return unread_->at(index);
61 } 96 }
62 97
63 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( 98 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex(
64 size_t index) const { 99 size_t index) const {
100 DCHECK_CURRENTLY_ON(web::WebThread::UI);
65 DCHECK(loaded()); 101 DCHECK(loaded());
66 return read_[index]; 102 return read_->at(index);
67 } 103 }
68 104
69 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( 105 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL(
70 const GURL& gurl) const { 106 const GURL& gurl) const {
71 DCHECK(loaded()); 107 DCHECK(loaded());
108 bool read;
109 return GetMutableEntryFromURL(gurl, read);
110 }
111
112 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL(
113 const GURL& gurl,
114 bool& read) const {
skym 2016/11/01 18:27:25 I think this is against Google C++ style, https://
Olivier 2016/11/02 14:57:10 Done.
115 DCHECK(loaded());
72 ReadingListEntry entry(gurl, std::string()); 116 ReadingListEntry entry(gurl, std::string());
73 auto it = std::find(read_.begin(), read_.end(), entry); 117 auto it = std::find(read_->begin(), read_->end(), entry);
74 if (it == read_.end()) { 118 read = true;
75 it = std::find(unread_.begin(), unread_.end(), entry); 119 if (it == read_->end()) {
76 if (it == unread_.end()) 120 it = std::find(unread_->begin(), unread_->end(), entry);
121 read = false;
122 if (it == unread_->end())
77 return nullptr; 123 return nullptr;
78 } 124 }
79 return &(*it); 125 return &(*it);
80 } 126 }
81 127
82 bool ReadingListModelImpl::CallbackEntryURL( 128 bool ReadingListModelImpl::CallbackEntryURL(
83 const GURL& url, 129 const GURL& url,
84 base::Callback<void(const ReadingListEntry&)> callback) const { 130 base::Callback<void(const ReadingListEntry&)> callback) const {
131 DCHECK_CURRENTLY_ON(web::WebThread::UI);
85 DCHECK(loaded()); 132 DCHECK(loaded());
86 const ReadingListEntry* entry = GetEntryFromURL(url); 133 bool read;
134 const ReadingListEntry* entry = GetMutableEntryFromURL(url, read);
87 if (entry) { 135 if (entry) {
88 callback.Run(*entry); 136 callback.Run(*entry);
89 return true; 137 return true;
90 } 138 }
91 return false; 139 return false;
92 } 140 }
93 141
94 void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { 142 bool ReadingListModelImpl::CallbackEntryReadStatusURL(
143 const GURL& url,
144 base::Callback<void(const ReadingListEntry&, bool read)> callback) const {
145 DCHECK_CURRENTLY_ON(web::WebThread::UI);
95 DCHECK(loaded()); 146 DCHECK(loaded());
96 const ReadingListEntry entry(url, std::string()); 147 bool read;
148 const ReadingListEntry* entry = GetMutableEntryFromURL(url, read);
149 if (entry) {
150 callback.Run(*entry, read);
151 return true;
152 }
153 return false;
154 }
97 155
98 auto result = std::find(unread_.begin(), unread_.end(), entry); 156 void ReadingListModelImpl::SyncAddEntry(std::unique_ptr<ReadingListEntry> entry,
99 if (result != unread_.end()) { 157 bool read) {
100 for (auto& observer : observers_) { 158 DCHECK_CURRENTLY_ON(web::WebThread::UI);
101 observer.ReadingListWillRemoveUnreadEntry( 159 DCHECK(loaded());
102 this, std::distance(unread_.begin(), result)); 160 bool is_entry_read;
skym 2016/11/01 18:27:25 Can you rename to make it clear this is for the ol
Olivier 2016/11/02 14:57:10 Done.
161 ReadingListEntry* existing_entry =
162 GetMutableEntryFromURL(entry->URL(), is_entry_read);
163 if (!existing_entry) {
164 if (storage_layer_) {
165 storage_layer_->SaveEntry(*entry, read, true);
103 } 166 }
104 unread_.erase(result); 167 if (read) {
105 if (storageLayer_ && !IsPerformingBatchUpdates()) 168 for (auto& observer : observers_)
106 storageLayer_->SavePersistentUnreadList(unread_); 169 observer.ReadingListWillAddReadEntry(this, *entry);
170 read_->insert(read_->begin(), std::move(*entry));
171 } else {
172 for (auto& observer : observers_)
173 observer.ReadingListWillAddUnreadEntry(this, *entry);
174 has_unseen_ = true;
175 SavePersistentHasUnseen(true);
176 unread_->insert(unread_->begin(), std::move(*entry));
177 }
107 for (auto& observer : observers_) 178 for (auto& observer : observers_)
108 observer.ReadingListDidApplyChanges(this); 179 observer.ReadingListDidApplyChanges(this);
skym 2016/11/01 18:27:25 I don't understand what these various observer met
Olivier 2016/11/02 14:57:10 You are right. Added ReadingListWillMoveEntry
109 return; 180 return;
110 } 181 }
111 182
112 result = std::find(read_.begin(), read_.end(), entry); 183 if (existing_entry->UpdateTime() > entry->UpdateTime()) {
113 if (result != read_.end()) { 184 // Existing entry is newer thatn sync one. Do not update it.
114 for (auto& observer : observers_) { 185 return;
115 observer.ReadingListWillRemoveReadEntry( 186 }
116 this, std::distance(read_.begin(), result)); 187
188 // Merge local data in new entry.
189 entry->MergeLocalStateFrom(*existing_entry);
190
191 if (is_entry_read) {
192 auto result = std::find(read_->begin(), read_->end(), *existing_entry);
skym 2016/11/01 18:27:25 There's a lot of std::find calls in here. They're
Olivier 2016/11/02 14:57:10 Yes, the number of entries should stay small
193 if (result != read_->end()) {
194 read_->erase(result);
skym 2016/11/01 18:27:25 If |is_entry_read| == |read|, then updating the ex
117 } 195 }
118 read_.erase(result); 196 } else {
119 if (storageLayer_ && !IsPerformingBatchUpdates()) 197 auto result = std::find(unread_->begin(), unread_->end(), *existing_entry);
120 storageLayer_->SavePersistentReadList(read_); 198 if (result != unread_->end()) {
199 unread_->erase(result);
200 }
201 }
202
203 if (storage_layer_) {
204 storage_layer_->SaveEntry(*entry, true, read);
skym 2016/11/01 18:27:25 Are the arguments |true| and |read| swapped here?
skym 2016/11/01 18:27:25 Also, kind of weird that the storage call is in th
Olivier 2016/11/02 14:57:10 Yes, thanks! Done.
Olivier 2016/11/02 14:57:10 It is there because there is a std::move on the ne
205 }
206
207 if (read) {
208 read_->push_back(std::move(*entry));
209 } else {
210 unread_->push_back(std::move(*entry));
211 }
212 }
213
214 void ReadingListModelImpl::SyncRemoveEntry(const GURL& gurl) {
215 RemoveEntryByUrlImpl(gurl, true);
216 }
217
218 void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) {
219 RemoveEntryByUrlImpl(url, false);
220 }
221
222 void ReadingListModelImpl::RemoveEntryByUrlImpl(const GURL& url,
223 bool from_sync) {
224 DCHECK_CURRENTLY_ON(web::WebThread::UI);
225 DCHECK(loaded());
226 const ReadingListEntry entry(url, std::string());
227
228 auto result = std::find(unread_->begin(), unread_->end(), entry);
229 if (result != unread_->end()) {
230 for (auto& observer : observers_)
231 observer.ReadingListWillRemoveUnreadEntry(
232 this, std::distance(unread_->begin(), result));
233
234 if (storage_layer_) {
235 storage_layer_->RemoveEntry(*result, from_sync);
236 }
237 unread_->erase(result);
238
121 for (auto& observer : observers_) 239 for (auto& observer : observers_)
122 observer.ReadingListDidApplyChanges(this); 240 observer.ReadingListDidApplyChanges(this);
123 return; 241 return;
242 }
243
244 result = std::find(read_->begin(), read_->end(), entry);
245 if (result != read_->end()) {
246 for (auto& observer : observers_)
247 observer.ReadingListWillRemoveReadEntry(
248 this, std::distance(read_->begin(), result));
249 if (storage_layer_) {
250 storage_layer_->RemoveEntry(*result, from_sync);
251 }
252 read_->erase(result);
253
254 for (auto& observer : observers_)
255 observer.ReadingListDidApplyChanges(this);
256 return;
124 } 257 }
125 } 258 }
126 259
127 const ReadingListEntry& ReadingListModelImpl::AddEntry( 260 const ReadingListEntry& ReadingListModelImpl::AddEntry(
128 const GURL& url, 261 const GURL& url,
129 const std::string& title) { 262 const std::string& title) {
263 DCHECK_CURRENTLY_ON(web::WebThread::UI);
130 DCHECK(loaded()); 264 DCHECK(loaded());
131 RemoveEntryByUrl(url); 265 RemoveEntryByUrl(url);
132 ReadingListEntry entry(url, title); 266 ReadingListEntry entry(url, title);
133 for (auto& observer : observers_) 267 for (auto& observer : observers_)
134 observer.ReadingListWillAddUnreadEntry(this, entry); 268 observer.ReadingListWillAddUnreadEntry(this, entry);
135 unread_.insert(unread_.begin(), std::move(entry)); 269 has_unseen_ = true;
136 hasUnseen_ = true; 270 SavePersistentHasUnseen(true);
137 if (storageLayer_ && !IsPerformingBatchUpdates()) { 271 if (storage_layer_) {
138 storageLayer_->SavePersistentUnreadList(unread_); 272 storage_layer_->SaveEntry(entry, false, false);
139 storageLayer_->SavePersistentHasUnseen(true);
140 } 273 }
274 unread_->insert(unread_->begin(), std::move(entry));
275
141 for (auto& observer : observers_) 276 for (auto& observer : observers_)
142 observer.ReadingListDidApplyChanges(this); 277 observer.ReadingListDidApplyChanges(this);
143 return *unread_.begin(); 278 return *unread_->begin();
144 } 279 }
145 280
146 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { 281 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) {
147 DCHECK(loaded()); 282 DCHECK(loaded());
148 ReadingListEntry entry(url, std::string()); 283 ReadingListEntry entry(url, std::string());
149 auto result = std::find(read_.begin(), read_.end(), entry); 284 auto result = std::find(read_->begin(), read_->end(), entry);
150 if (result == read_.end()) 285 if (result == read_->end())
151 return; 286 return;
152 287
153 for (ReadingListModelObserver& observer : observers_) { 288 for (ReadingListModelObserver& observer : observers_) {
154 observer.ReadingListWillMoveEntry(this, 289 observer.ReadingListWillMoveEntry(this,
155 std::distance(read_.begin(), result)); 290 std::distance(read_->begin(), result));
156 } 291 }
157 292
158 unread_.insert(unread_.begin(), std::move(*result)); 293 result->MarkEntryUpdated();
159 read_.erase(result); 294 if (storage_layer_) {
295 storage_layer_->SaveEntry(*result, false, false);
296 }
160 297
161 if (storageLayer_ && !IsPerformingBatchUpdates()) { 298 unread_->insert(unread_->begin(), std::move(*result));
162 storageLayer_->SavePersistentUnreadList(read_); 299 read_->erase(result);
163 storageLayer_->SavePersistentReadList(unread_); 300
164 }
165 for (ReadingListModelObserver& observer : observers_) { 301 for (ReadingListModelObserver& observer : observers_) {
166 observer.ReadingListDidApplyChanges(this); 302 observer.ReadingListDidApplyChanges(this);
167 } 303 }
168 } 304 }
169 305
170 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { 306 void ReadingListModelImpl::MarkReadByURL(const GURL& url) {
307 DCHECK_CURRENTLY_ON(web::WebThread::UI);
171 DCHECK(loaded()); 308 DCHECK(loaded());
172 ReadingListEntry entry(url, std::string()); 309 ReadingListEntry entry(url, std::string());
173 auto result = std::find(unread_.begin(), unread_.end(), entry); 310 auto result = std::find(unread_->begin(), unread_->end(), entry);
174 if (result == unread_.end()) 311 if (result == unread_->end())
175 return; 312 return;
176 313
177 for (auto& observer : observers_) { 314 for (auto& observer : observers_)
178 observer.ReadingListWillMoveEntry(this, 315 observer.ReadingListWillMoveEntry(this,
179 std::distance(unread_.begin(), result)); 316 std::distance(unread_->begin(), result));
317
318 result->MarkEntryUpdated();
319 if (storage_layer_) {
320 storage_layer_->SaveEntry(*result, true, false);
180 } 321 }
181 322
182 read_.insert(read_.begin(), std::move(*result)); 323 read_->insert(read_->begin(), std::move(*result));
183 unread_.erase(result); 324 unread_->erase(result);
184 325
185 if (storageLayer_ && !IsPerformingBatchUpdates()) {
186 storageLayer_->SavePersistentUnreadList(unread_);
187 storageLayer_->SavePersistentReadList(read_);
188 }
189 for (auto& observer : observers_) 326 for (auto& observer : observers_)
190 observer.ReadingListDidApplyChanges(this); 327 observer.ReadingListDidApplyChanges(this);
191 } 328 }
192 329
193 void ReadingListModelImpl::SetEntryTitle(const GURL& url, 330 void ReadingListModelImpl::SetEntryTitle(const GURL& url,
194 const std::string& title) { 331 const std::string& title) {
332 DCHECK_CURRENTLY_ON(web::WebThread::UI);
195 DCHECK(loaded()); 333 DCHECK(loaded());
196 const ReadingListEntry entry(url, std::string()); 334 const ReadingListEntry entry(url, std::string());
197 335
198 auto result = std::find(unread_.begin(), unread_.end(), entry); 336 auto result = std::find(unread_->begin(), unread_->end(), entry);
199 if (result != unread_.end()) { 337 if (result != unread_->end()) {
200 for (auto& observer : observers_) { 338 for (auto& observer : observers_)
201 observer.ReadingListWillUpdateUnreadEntry( 339 observer.ReadingListWillUpdateUnreadEntry(
202 this, std::distance(unread_.begin(), result)); 340 this, std::distance(unread_->begin(), result));
341 result->SetTitle(title);
342
343 if (storage_layer_) {
344 storage_layer_->SaveEntry(*result, false, false);
203 } 345 }
204 result->SetTitle(title);
205 if (storageLayer_ && !IsPerformingBatchUpdates())
206 storageLayer_->SavePersistentUnreadList(unread_);
207 for (auto& observer : observers_) 346 for (auto& observer : observers_)
208 observer.ReadingListDidApplyChanges(this); 347 observer.ReadingListDidApplyChanges(this);
209 return; 348 return;
210 } 349 }
211 350
212 result = std::find(read_.begin(), read_.end(), entry); 351 result = std::find(read_->begin(), read_->end(), entry);
213 if (result != read_.end()) { 352 if (result != read_->end()) {
214 for (auto& observer : observers_) { 353 for (auto& observer : observers_)
215 observer.ReadingListWillUpdateReadEntry( 354 observer.ReadingListWillUpdateReadEntry(
216 this, std::distance(read_.begin(), result)); 355 this, std::distance(read_->begin(), result));
356 result->SetTitle(title);
357 if (storage_layer_) {
358 storage_layer_->SaveEntry(*result, true, false);
217 } 359 }
218 result->SetTitle(title);
219 if (storageLayer_ && !IsPerformingBatchUpdates())
220 storageLayer_->SavePersistentReadList(read_);
221 for (auto& observer : observers_) 360 for (auto& observer : observers_)
222 observer.ReadingListDidApplyChanges(this); 361 observer.ReadingListDidApplyChanges(this);
223 return; 362 return;
224 } 363 }
225 } 364 }
226 365
227 void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, 366 void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url,
228 const GURL& distilled_url) { 367 const GURL& distilled_url) {
368 DCHECK_CURRENTLY_ON(web::WebThread::UI);
229 DCHECK(loaded()); 369 DCHECK(loaded());
230 const ReadingListEntry entry(url, std::string()); 370 const ReadingListEntry entry(url, std::string());
231 371
232 auto result = std::find(unread_.begin(), unread_.end(), entry); 372 auto result = std::find(unread_->begin(), unread_->end(), entry);
233 if (result != unread_.end()) { 373 if (result != unread_->end()) {
234 for (auto& observer : observers_) { 374 for (auto& observer : observers_)
235 observer.ReadingListWillUpdateUnreadEntry( 375 observer.ReadingListWillUpdateUnreadEntry(
236 this, std::distance(unread_.begin(), result)); 376 this, std::distance(unread_->begin(), result));
377 result->SetDistilledURL(distilled_url);
378 if (storage_layer_) {
379 storage_layer_->SaveEntry(*result, false, false);
237 } 380 }
238 result->SetDistilledURL(distilled_url);
239 if (storageLayer_ && !IsPerformingBatchUpdates())
240 storageLayer_->SavePersistentUnreadList(unread_);
241 for (auto& observer : observers_) 381 for (auto& observer : observers_)
242 observer.ReadingListDidApplyChanges(this); 382 observer.ReadingListDidApplyChanges(this);
243 return; 383 return;
244 } 384 }
245 385
246 result = std::find(read_.begin(), read_.end(), entry); 386 result = std::find(read_->begin(), read_->end(), entry);
247 if (result != read_.end()) { 387 if (result != read_->end()) {
248 for (auto& observer : observers_) { 388 for (auto& observer : observers_)
249 observer.ReadingListWillUpdateReadEntry( 389 observer.ReadingListWillUpdateReadEntry(
250 this, std::distance(read_.begin(), result)); 390 this, std::distance(read_->begin(), result));
391 result->SetDistilledURL(distilled_url);
392 if (storage_layer_) {
393 storage_layer_->SaveEntry(*result, true, false);
251 } 394 }
252 result->SetDistilledURL(distilled_url);
253 if (storageLayer_ && !IsPerformingBatchUpdates())
254 storageLayer_->SavePersistentReadList(read_);
255 for (auto& observer : observers_) 395 for (auto& observer : observers_)
256 observer.ReadingListDidApplyChanges(this); 396 observer.ReadingListDidApplyChanges(this);
257 return; 397 return;
258 } 398 }
259 } 399 }
260 400
261 void ReadingListModelImpl::SetEntryDistilledState( 401 void ReadingListModelImpl::SetEntryDistilledState(
262 const GURL& url, 402 const GURL& url,
263 ReadingListEntry::DistillationState state) { 403 ReadingListEntry::DistillationState state) {
404 DCHECK_CURRENTLY_ON(web::WebThread::UI);
264 DCHECK(loaded()); 405 DCHECK(loaded());
265 const ReadingListEntry entry(url, std::string()); 406 const ReadingListEntry entry(url, std::string());
266 407
267 auto result = std::find(unread_.begin(), unread_.end(), entry); 408 auto result = std::find(unread_->begin(), unread_->end(), entry);
268 if (result != unread_.end()) { 409 if (result != unread_->end()) {
269 for (auto& observer : observers_) { 410 for (auto& observer : observers_)
270 observer.ReadingListWillUpdateUnreadEntry( 411 observer.ReadingListWillUpdateUnreadEntry(
271 this, std::distance(unread_.begin(), result)); 412 this, std::distance(unread_->begin(), result));
413 result->SetDistilledState(state);
414 if (storage_layer_) {
415 storage_layer_->SaveEntry(*result, false, false);
272 } 416 }
273 result->SetDistilledState(state);
274 if (storageLayer_ && !IsPerformingBatchUpdates())
275 storageLayer_->SavePersistentUnreadList(unread_);
276 for (auto& observer : observers_) 417 for (auto& observer : observers_)
277 observer.ReadingListDidApplyChanges(this); 418 observer.ReadingListDidApplyChanges(this);
278 return; 419 return;
279 } 420 }
280 421
281 result = std::find(read_.begin(), read_.end(), entry); 422 result = std::find(read_->begin(), read_->end(), entry);
282 if (result != read_.end()) { 423 if (result != read_->end()) {
283 for (auto& observer : observers_) { 424 for (auto& observer : observers_)
284 observer.ReadingListWillUpdateReadEntry( 425 observer.ReadingListWillUpdateReadEntry(
285 this, std::distance(read_.begin(), result)); 426 this, std::distance(read_->begin(), result));
427 result->SetDistilledState(state);
428 if (storage_layer_) {
429 storage_layer_->SaveEntry(*result, true, false);
286 } 430 }
287 result->SetDistilledState(state);
288 if (storageLayer_ && !IsPerformingBatchUpdates())
289 storageLayer_->SavePersistentReadList(read_);
290 for (auto& observer : observers_) 431 for (auto& observer : observers_)
291 observer.ReadingListDidApplyChanges(this); 432 observer.ReadingListDidApplyChanges(this);
292 return; 433 return;
293 } 434 }
294 }; 435 };
295 436
296 void ReadingListModelImpl::EndBatchUpdates() { 437 void ReadingListModelImpl::LeavingBatchUpdates() {
297 ReadingListModel::EndBatchUpdates(); 438 DCHECK_CURRENTLY_ON(web::WebThread::UI);
298 if (IsPerformingBatchUpdates() || !storageLayer_) { 439 ReadingListModel::LeavingBatchUpdates();
440 if (storage_layer_) {
441 SavePersistentHasUnseen(has_unseen_);
442 storage_layer_->CommitTransaction();
443 SortEntries();
444 }
445 }
446
447 void ReadingListModelImpl::EnteringBatchUpdates() {
448 DCHECK_CURRENTLY_ON(web::WebThread::UI);
449 if (storage_layer_) {
450 storage_layer_->BeginTransaction();
451 }
452 ReadingListModel::EnteringBatchUpdates();
453 }
454
455 void ReadingListModelImpl::SavePersistentHasUnseen(bool has_unseen) {
456 DCHECK_CURRENTLY_ON(web::WebThread::UI);
457 if (!pref_service_) {
299 return; 458 return;
300 } 459 }
301 storageLayer_->SavePersistentUnreadList(unread_); 460 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries,
302 storageLayer_->SavePersistentReadList(read_); 461 has_unseen);
303 storageLayer_->SavePersistentHasUnseen(hasUnseen_);
304 } 462 }
463
464 bool ReadingListModelImpl::LoadPersistentHasUnseen() {
465 DCHECK_CURRENTLY_ON(web::WebThread::UI);
466 if (!pref_service_) {
467 return false;
468 }
469 return pref_service_->GetBoolean(
470 reading_list::prefs::kReadingListHasUnseenEntries);
471 }
472
473 syncer::ModelTypeService* ReadingListModelImpl::GetModelTypeService() {
474 return storage_layer_->GetModelTypeService();
475 }
476
477 void ReadingListModelImpl::SortEntries() {
478 std::sort(read_->begin(), read_->end(),
479 ReadingListEntry::CompareEntryUpdateTime);
480 std::sort(unread_->begin(), unread_->end(),
481 ReadingListEntry::CompareEntryUpdateTime);
482 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698