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

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

Issue 2369303002: Reading List create protobuf store (Closed)
Patch Set: feedback Created 4 years, 2 months 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 storage_layer_->LoadPersistentLists();
19 hasUnseen_ = storageLayer_->LoadPersistentHasUnseen(); 31 } else {
32 loaded_ = true;
33 read_ = base::MakeUnique<ReadingListEntries>();
34 unread_ = base::MakeUnique<ReadingListEntries>();
20 } 35 }
21 loaded_ = true; 36 has_unseen_ = LoadPersistentHasUnseen();
22 } 37 }
23 ReadingListModelImpl::~ReadingListModelImpl() {} 38 ReadingListModelImpl::~ReadingListModelImpl() {}
24 39
40 void ReadingListModelImpl::ModelLoaded(
41 std::unique_ptr<ReadingListEntries> unread,
42 std::unique_ptr<ReadingListEntries> read) {
43 DCHECK_CURRENTLY_ON(web::WebThread::UI);
44 read_ = std::move(read);
45 unread_ = std::move(unread);
46 loaded_ = true;
47 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
48 ReadingListModelLoaded(this));
49 }
50
25 void ReadingListModelImpl::Shutdown() { 51 void ReadingListModelImpl::Shutdown() {
52 DCHECK_CURRENTLY_ON(web::WebThread::UI);
26 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 53 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
27 ReadingListModelBeingDeleted(this)); 54 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 // Returns a specific entry. 91 // Returns a specific entry.
58 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( 92 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex(
59 size_t index) const { 93 size_t index) const {
94 DCHECK_CURRENTLY_ON(web::WebThread::UI);
60 DCHECK(loaded()); 95 DCHECK(loaded());
61 return unread_[index]; 96 return unread_->at(index);
62 } 97 }
63 98
64 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( 99 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex(
65 size_t index) const { 100 size_t index) const {
101 DCHECK_CURRENTLY_ON(web::WebThread::UI);
66 DCHECK(loaded()); 102 DCHECK(loaded());
67 return read_[index]; 103 return read_->at(index);
68 } 104 }
69 105
70 bool ReadingListModelImpl::CallbackEntryURL( 106 bool ReadingListModelImpl::CallbackEntryURL(
71 const GURL& url, 107 const GURL& url,
72 base::Callback<void(const ReadingListEntry&)> callback) const { 108 base::Callback<void(const ReadingListEntry&)> callback) const {
109 DCHECK_CURRENTLY_ON(web::WebThread::UI);
73 DCHECK(loaded()); 110 DCHECK(loaded());
74 ReadingListEntry entry(url, std::string()); 111 ReadingListEntry entry(url, std::string());
75 auto resultUnread = std::find(unread_.begin(), unread_.end(), entry); 112 auto resultUnread = std::find(unread_->begin(), unread_->end(), entry);
76 if (resultUnread != unread_.end()) { 113 if (resultUnread != unread_->end()) {
77 callback.Run(*resultUnread); 114 callback.Run(*resultUnread);
78 return true; 115 return true;
79 } 116 }
80 117
81 auto resultRead = std::find(read_.begin(), read_.end(), entry); 118 auto resultRead = std::find(read_->begin(), read_->end(), entry);
82 if (resultRead != read_.end()) { 119 if (resultRead != read_->end()) {
83 callback.Run(*resultRead); 120 callback.Run(*resultRead);
84 return true; 121 return true;
85 } 122 }
86 return false; 123 return false;
87 } 124 }
88 125
89 void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { 126 void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) {
127 DCHECK_CURRENTLY_ON(web::WebThread::UI);
90 DCHECK(loaded()); 128 DCHECK(loaded());
91 const ReadingListEntry entry(url, std::string()); 129 const ReadingListEntry entry(url, std::string());
92 130
93 auto result = std::find(unread_.begin(), unread_.end(), entry); 131 auto result = std::find(unread_->begin(), unread_->end(), entry);
94 if (result != unread_.end()) { 132 if (result != unread_->end()) {
95 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 133 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
96 ReadingListWillRemoveUnreadEntry( 134 ReadingListWillRemoveUnreadEntry(
97 this, std::distance(unread_.begin(), result))); 135 this, std::distance(unread_->begin(), result)));
98 unread_.erase(result); 136 unread_->erase(result);
99 if (storageLayer_ && !IsPerformingBatchUpdates()) 137
100 storageLayer_->SavePersistentUnreadList(unread_); 138 if (storage_layer_) {
139 storage_layer_->RemoveEntry(*result);
140 }
141
101 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 142 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
102 ReadingListDidApplyChanges(this)); 143 ReadingListDidApplyChanges(this));
103 return; 144 return;
104 } 145 }
105 146
106 result = std::find(read_.begin(), read_.end(), entry); 147 result = std::find(read_->begin(), read_->end(), entry);
107 if (result != read_.end()) { 148 if (result != read_->end()) {
108 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 149 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
109 ReadingListWillRemoveReadEntry( 150 ReadingListWillRemoveReadEntry(
110 this, std::distance(read_.begin(), result))); 151 this, std::distance(read_->begin(), result)));
111 read_.erase(result); 152 read_->erase(result);
112 if (storageLayer_ && !IsPerformingBatchUpdates()) 153
113 storageLayer_->SavePersistentReadList(read_); 154 if (storage_layer_) {
155 storage_layer_->RemoveEntry(*result);
156 }
157
114 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 158 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
115 ReadingListDidApplyChanges(this)); 159 ReadingListDidApplyChanges(this));
116 return; 160 return;
117 } 161 }
118 } 162 }
119 163
120 const ReadingListEntry& ReadingListModelImpl::AddEntry( 164 const ReadingListEntry& ReadingListModelImpl::AddEntry(
121 const GURL& url, 165 const GURL& url,
122 const std::string& title) { 166 const std::string& title) {
167 DCHECK_CURRENTLY_ON(web::WebThread::UI);
123 DCHECK(loaded()); 168 DCHECK(loaded());
124 RemoveEntryByUrl(url); 169 RemoveEntryByUrl(url);
125 ReadingListEntry entry(url, title); 170 ReadingListEntry entry(url, title);
126 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 171 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
127 ReadingListWillAddUnreadEntry(this, entry)); 172 ReadingListWillAddUnreadEntry(this, entry));
128 unread_.insert(unread_.begin(), std::move(entry)); 173 has_unseen_ = true;
129 hasUnseen_ = true; 174 SavePersistentHasUnseen(true);
130 if (storageLayer_ && !IsPerformingBatchUpdates()) { 175 if (storage_layer_) {
131 storageLayer_->SavePersistentUnreadList(unread_); 176 storage_layer_->SaveEntry(entry, false);
132 storageLayer_->SavePersistentHasUnseen(true);
133 } 177 }
178 unread_->insert(unread_->begin(), std::move(entry));
179
134 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 180 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
135 ReadingListDidApplyChanges(this)); 181 ReadingListDidApplyChanges(this));
136 return *unread_.begin(); 182 return *unread_->begin();
137 } 183 }
138 184
139 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { 185 void ReadingListModelImpl::MarkReadByURL(const GURL& url) {
186 DCHECK_CURRENTLY_ON(web::WebThread::UI);
140 DCHECK(loaded()); 187 DCHECK(loaded());
141 ReadingListEntry entry(url, std::string()); 188 ReadingListEntry entry(url, std::string());
142 auto result = std::find(unread_.begin(), unread_.end(), entry); 189 auto result = std::find(unread_->begin(), unread_->end(), entry);
143 if (result == unread_.end()) 190 if (result == unread_->end())
144 return; 191 return;
145 192
146 FOR_EACH_OBSERVER( 193 FOR_EACH_OBSERVER(
147 ReadingListModelObserver, observers_, 194 ReadingListModelObserver, observers_,
148 ReadingListWillMoveEntry(this, std::distance(unread_.begin(), result))); 195 ReadingListWillMoveEntry(this, std::distance(unread_->begin(), result)));
149 196
150 read_.insert(read_.begin(), std::move(*result)); 197 result->MarkEntryUpdated();
151 unread_.erase(result); 198 if (storage_layer_) {
199 storage_layer_->SaveEntry(*result, true);
200 }
152 201
153 if (storageLayer_ && !IsPerformingBatchUpdates()) { 202 read_->insert(read_->begin(), std::move(*result));
154 storageLayer_->SavePersistentUnreadList(unread_); 203 unread_->erase(result);
155 storageLayer_->SavePersistentReadList(read_); 204
156 }
157 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 205 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
158 ReadingListDidApplyChanges(this)); 206 ReadingListDidApplyChanges(this));
159 } 207 }
160 208
161 void ReadingListModelImpl::SetEntryTitle(const GURL& url, 209 void ReadingListModelImpl::SetEntryTitle(const GURL& url,
162 const std::string& title) { 210 const std::string& title) {
211 DCHECK_CURRENTLY_ON(web::WebThread::UI);
163 DCHECK(loaded()); 212 DCHECK(loaded());
164 const ReadingListEntry entry(url, std::string()); 213 const ReadingListEntry entry(url, std::string());
165 214
166 auto result = std::find(unread_.begin(), unread_.end(), entry); 215 auto result = std::find(unread_->begin(), unread_->end(), entry);
167 if (result != unread_.end()) { 216 if (result != unread_->end()) {
168 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 217 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
169 ReadingListWillUpdateUnreadEntry( 218 ReadingListWillUpdateUnreadEntry(
170 this, std::distance(unread_.begin(), result))); 219 this, std::distance(unread_->begin(), result)));
171 result->SetTitle(title); 220 result->SetTitle(title);
172 if (storageLayer_ && !IsPerformingBatchUpdates()) 221
173 storageLayer_->SavePersistentUnreadList(unread_); 222 if (storage_layer_) {
223 storage_layer_->SaveEntry(*result, false);
224 }
174 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 225 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
175 ReadingListDidApplyChanges(this)); 226 ReadingListDidApplyChanges(this));
176 return; 227 return;
177 } 228 }
178 229
179 result = std::find(read_.begin(), read_.end(), entry); 230 result = std::find(read_->begin(), read_->end(), entry);
180 if (result != read_.end()) { 231 if (result != read_->end()) {
181 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 232 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
182 ReadingListWillUpdateReadEntry( 233 ReadingListWillUpdateReadEntry(
183 this, std::distance(read_.begin(), result))); 234 this, std::distance(read_->begin(), result)));
184 result->SetTitle(title); 235 result->SetTitle(title);
185 if (storageLayer_ && !IsPerformingBatchUpdates()) 236 if (storage_layer_) {
186 storageLayer_->SavePersistentReadList(read_); 237 storage_layer_->SaveEntry(*result, true);
238 }
187 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 239 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
188 ReadingListDidApplyChanges(this)); 240 ReadingListDidApplyChanges(this));
189 return; 241 return;
190 } 242 }
191 } 243 }
192 244
193 void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, 245 void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url,
194 const GURL& distilled_url) { 246 const GURL& distilled_url) {
247 DCHECK_CURRENTLY_ON(web::WebThread::UI);
195 DCHECK(loaded()); 248 DCHECK(loaded());
196 const ReadingListEntry entry(url, std::string()); 249 const ReadingListEntry entry(url, std::string());
197 250
198 auto result = std::find(unread_.begin(), unread_.end(), entry); 251 auto result = std::find(unread_->begin(), unread_->end(), entry);
199 if (result != unread_.end()) { 252 if (result != unread_->end()) {
200 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 253 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
201 ReadingListWillUpdateUnreadEntry( 254 ReadingListWillUpdateUnreadEntry(
202 this, std::distance(unread_.begin(), result))); 255 this, std::distance(unread_->begin(), result)));
203 result->SetDistilledURL(distilled_url); 256 result->SetDistilledURL(distilled_url);
204 if (storageLayer_ && !IsPerformingBatchUpdates()) 257 if (storage_layer_) {
205 storageLayer_->SavePersistentUnreadList(unread_); 258 storage_layer_->SaveEntry(*result, false);
259 }
206 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 260 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
207 ReadingListDidApplyChanges(this)); 261 ReadingListDidApplyChanges(this));
208 return; 262 return;
209 } 263 }
210 264
211 result = std::find(read_.begin(), read_.end(), entry); 265 result = std::find(read_->begin(), read_->end(), entry);
212 if (result != read_.end()) { 266 if (result != read_->end()) {
213 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 267 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
214 ReadingListWillUpdateReadEntry( 268 ReadingListWillUpdateReadEntry(
215 this, std::distance(read_.begin(), result))); 269 this, std::distance(read_->begin(), result)));
216 result->SetDistilledURL(distilled_url); 270 result->SetDistilledURL(distilled_url);
217 if (storageLayer_ && !IsPerformingBatchUpdates()) 271 if (storage_layer_) {
218 storageLayer_->SavePersistentReadList(read_); 272 storage_layer_->SaveEntry(*result, true);
273 }
219 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 274 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
220 ReadingListDidApplyChanges(this)); 275 ReadingListDidApplyChanges(this));
221 return; 276 return;
222 } 277 }
223 } 278 }
224 279
225 void ReadingListModelImpl::SetEntryDistilledState( 280 void ReadingListModelImpl::SetEntryDistilledState(
226 const GURL& url, 281 const GURL& url,
227 ReadingListEntry::DistillationState state) { 282 ReadingListEntry::DistillationState state) {
283 DCHECK_CURRENTLY_ON(web::WebThread::UI);
228 DCHECK(loaded()); 284 DCHECK(loaded());
229 const ReadingListEntry entry(url, std::string()); 285 const ReadingListEntry entry(url, std::string());
230 286
231 auto result = std::find(unread_.begin(), unread_.end(), entry); 287 auto result = std::find(unread_->begin(), unread_->end(), entry);
232 if (result != unread_.end()) { 288 if (result != unread_->end()) {
233 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 289 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
234 ReadingListWillUpdateUnreadEntry( 290 ReadingListWillUpdateUnreadEntry(
235 this, std::distance(unread_.begin(), result))); 291 this, std::distance(unread_->begin(), result)));
236 result->SetDistilledState(state); 292 result->SetDistilledState(state);
237 if (storageLayer_ && !IsPerformingBatchUpdates()) 293 if (storage_layer_) {
238 storageLayer_->SavePersistentUnreadList(unread_); 294 storage_layer_->SaveEntry(*result, false);
295 }
239 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 296 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
240 ReadingListDidApplyChanges(this)); 297 ReadingListDidApplyChanges(this));
241 return; 298 return;
242 } 299 }
243 300
244 result = std::find(read_.begin(), read_.end(), entry); 301 result = std::find(read_->begin(), read_->end(), entry);
245 if (result != read_.end()) { 302 if (result != read_->end()) {
246 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 303 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
247 ReadingListWillUpdateReadEntry( 304 ReadingListWillUpdateReadEntry(
248 this, std::distance(read_.begin(), result))); 305 this, std::distance(read_->begin(), result)));
249 result->SetDistilledState(state); 306 result->SetDistilledState(state);
250 if (storageLayer_ && !IsPerformingBatchUpdates()) 307 if (storage_layer_) {
251 storageLayer_->SavePersistentReadList(read_); 308 storage_layer_->SaveEntry(*result, true);
309 }
252 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, 310 FOR_EACH_OBSERVER(ReadingListModelObserver, observers_,
253 ReadingListDidApplyChanges(this)); 311 ReadingListDidApplyChanges(this));
254 return; 312 return;
255 } 313 }
256 }; 314 };
257 315
258 void ReadingListModelImpl::EndBatchUpdates() { 316 void ReadingListModelImpl::LeavingBatchUpdates() {
259 ReadingListModel::EndBatchUpdates(); 317 DCHECK_CURRENTLY_ON(web::WebThread::UI);
260 if (IsPerformingBatchUpdates() || !storageLayer_) { 318 ReadingListModel::LeavingBatchUpdates();
319 if (storage_layer_) {
320 SavePersistentHasUnseen(has_unseen_);
321 storage_layer_->CommitTransaction();
322 }
323 }
324
325 void ReadingListModelImpl::EnteringBatchUpdates() {
326 DCHECK_CURRENTLY_ON(web::WebThread::UI);
327 if (storage_layer_) {
328 storage_layer_->BeginTransaction();
329 }
330 ReadingListModel::EnteringBatchUpdates();
331 }
332
333 void ReadingListModelImpl::SavePersistentHasUnseen(bool has_unseen) {
334 DCHECK_CURRENTLY_ON(web::WebThread::UI);
335 if (!pref_service_) {
261 return; 336 return;
262 } 337 }
263 storageLayer_->SavePersistentUnreadList(unread_); 338 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries,
264 storageLayer_->SavePersistentReadList(read_); 339 has_unseen);
265 storageLayer_->SavePersistentHasUnseen(hasUnseen_);
266 } 340 }
341
342 bool ReadingListModelImpl::LoadPersistentHasUnseen() {
343 DCHECK_CURRENTLY_ON(web::WebThread::UI);
344 if (!pref_service_) {
345 return false;
346 }
347 return pref_service_->GetBoolean(
348 reading_list::prefs::kReadingListHasUnseenEntries);
349 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698