OLD | NEW |
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 |
| 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()); |
| 163 DCHECK(loaded()); |
| 164 // entry must not already exist. |
| 165 DCHECK(GetMutableEntryFromURL(entry->URL(), nullptr) == nullptr); |
| 166 if (read) { |
| 167 for (auto& observer : observers_) |
| 168 observer.ReadingListWillAddReadEntry(this, *entry); |
| 169 read_->insert(read_->begin(), std::move(*entry)); |
| 170 } else { |
| 171 for (auto& observer : observers_) |
| 172 observer.ReadingListWillAddUnreadEntry(this, *entry); |
| 173 has_unseen_ = true; |
| 174 SetPersistentHasUnseen(true); |
| 175 unread_->insert(unread_->begin(), std::move(*entry)); |
| 176 } |
| 177 for (auto& observer : observers_) |
| 178 observer.ReadingListDidApplyChanges(this); |
| 179 } |
| 180 |
| 181 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry( |
| 182 std::unique_ptr<ReadingListEntry> entry, |
| 183 bool read) { |
| 184 DCHECK(CalledOnValidThread()); |
| 185 DCHECK(loaded()); |
| 186 bool is_existing_entry_read; |
| 187 ReadingListEntry* existing_entry = |
| 188 GetMutableEntryFromURL(entry->URL(), &is_existing_entry_read); |
| 189 |
| 190 DCHECK(existing_entry); |
| 191 DCHECK(existing_entry->UpdateTime() < entry->UpdateTime()); |
| 192 |
| 193 // Merge local data in new entry. |
| 194 entry->MergeLocalStateFrom(*existing_entry); |
| 195 |
| 196 if (is_existing_entry_read) { |
| 197 MoveEntryFrom(read_.get(), *existing_entry, true); |
| 198 } else { |
| 199 MoveEntryFrom(unread_.get(), *existing_entry, false); |
| 200 } |
| 201 |
| 202 ReadingListEntries::iterator added_iterator; |
| 203 if (read) { |
| 204 read_->push_back(std::move(*entry)); |
| 205 added_iterator = read_->end() - 1; |
| 206 } else { |
| 207 unread_->push_back(std::move(*entry)); |
| 208 added_iterator = unread_->end() - 1; |
| 209 } |
| 210 for (auto& observer : observers_) |
| 211 observer.ReadingListDidApplyChanges(this); |
| 212 |
| 213 ReadingListEntry& merged_entry = *added_iterator; |
| 214 return &merged_entry; |
| 215 } |
| 216 |
| 217 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) { |
| 218 RemoveEntryByURLImpl(url, true); |
| 219 } |
| 220 |
100 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { | 221 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { |
| 222 RemoveEntryByURLImpl(url, false); |
| 223 } |
| 224 |
| 225 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, |
| 226 bool from_sync) { |
| 227 DCHECK(CalledOnValidThread()); |
101 DCHECK(loaded()); | 228 DCHECK(loaded()); |
102 const ReadingListEntry entry(url, std::string()); | 229 const ReadingListEntry entry(url, std::string()); |
103 | 230 |
104 auto result = std::find(unread_.begin(), unread_.end(), entry); | 231 auto result = std::find(unread_->begin(), unread_->end(), entry); |
105 if (result != unread_.end()) { | 232 if (result != unread_->end()) { |
106 for (auto& observer : observers_) { | 233 for (auto& observer : observers_) |
107 observer.ReadingListWillRemoveUnreadEntry( | 234 observer.ReadingListWillRemoveUnreadEntry( |
108 this, std::distance(unread_.begin(), result)); | 235 this, std::distance(unread_->begin(), result)); |
| 236 |
| 237 if (storage_layer_ && !from_sync) { |
| 238 storage_layer_->RemoveEntry(*result); |
109 } | 239 } |
110 unread_.erase(result); | 240 unread_->erase(result); |
111 if (storage_layer_ && !IsPerformingBatchUpdates()) | 241 |
112 storage_layer_->SavePersistentUnreadList(unread_); | |
113 for (auto& observer : observers_) | 242 for (auto& observer : observers_) |
114 observer.ReadingListDidApplyChanges(this); | 243 observer.ReadingListDidApplyChanges(this); |
115 return; | 244 return; |
116 } | 245 } |
117 | 246 |
118 result = std::find(read_.begin(), read_.end(), entry); | 247 result = std::find(read_->begin(), read_->end(), entry); |
119 if (result != read_.end()) { | 248 if (result != read_->end()) { |
120 for (auto& observer : observers_) { | 249 for (auto& observer : observers_) |
121 observer.ReadingListWillRemoveReadEntry( | 250 observer.ReadingListWillRemoveReadEntry( |
122 this, std::distance(read_.begin(), result)); | 251 this, std::distance(read_->begin(), result)); |
| 252 if (storage_layer_ && !from_sync) { |
| 253 storage_layer_->RemoveEntry(*result); |
123 } | 254 } |
124 read_.erase(result); | 255 read_->erase(result); |
125 if (storage_layer_ && !IsPerformingBatchUpdates()) | 256 |
126 storage_layer_->SavePersistentReadList(read_); | |
127 for (auto& observer : observers_) | 257 for (auto& observer : observers_) |
128 observer.ReadingListDidApplyChanges(this); | 258 observer.ReadingListDidApplyChanges(this); |
129 return; | 259 return; |
130 } | 260 } |
131 } | 261 } |
132 | 262 |
133 const ReadingListEntry& ReadingListModelImpl::AddEntry( | 263 const ReadingListEntry& ReadingListModelImpl::AddEntry( |
134 const GURL& url, | 264 const GURL& url, |
135 const std::string& title) { | 265 const std::string& title) { |
| 266 DCHECK(CalledOnValidThread()); |
136 DCHECK(loaded()); | 267 DCHECK(loaded()); |
137 RemoveEntryByURL(url); | 268 RemoveEntryByURL(url); |
138 | 269 |
139 std::string trimmedTitle(title); | 270 std::string trimmedTitle(title); |
140 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle); | 271 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle); |
141 | 272 |
142 ReadingListEntry entry(url, trimmedTitle); | 273 ReadingListEntry entry(url, trimmedTitle); |
143 for (auto& observer : observers_) | 274 for (auto& observer : observers_) |
144 observer.ReadingListWillAddUnreadEntry(this, entry); | 275 observer.ReadingListWillAddUnreadEntry(this, entry); |
145 unread_.insert(unread_.begin(), std::move(entry)); | |
146 has_unseen_ = true; | 276 has_unseen_ = true; |
147 if (storage_layer_ && !IsPerformingBatchUpdates()) { | 277 SetPersistentHasUnseen(true); |
148 storage_layer_->SavePersistentUnreadList(unread_); | 278 if (storage_layer_) { |
149 SetPersistentHasUnseen(true); | 279 storage_layer_->SaveEntry(entry, false); |
150 } | 280 } |
| 281 unread_->insert(unread_->begin(), std::move(entry)); |
| 282 |
151 for (auto& observer : observers_) | 283 for (auto& observer : observers_) |
152 observer.ReadingListDidApplyChanges(this); | 284 observer.ReadingListDidApplyChanges(this); |
153 return *unread_.begin(); | 285 return *unread_->begin(); |
154 } | 286 } |
155 | 287 |
156 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { | 288 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { |
| 289 DCHECK(CalledOnValidThread()); |
157 DCHECK(loaded()); | 290 DCHECK(loaded()); |
158 ReadingListEntry entry(url, std::string()); | 291 ReadingListEntry entry(url, std::string()); |
159 auto result = std::find(read_.begin(), read_.end(), entry); | 292 auto result = std::find(read_->begin(), read_->end(), entry); |
160 if (result == read_.end()) | 293 if (result == read_->end()) |
161 return; | 294 return; |
162 | 295 |
163 for (ReadingListModelObserver& observer : observers_) { | 296 for (ReadingListModelObserver& observer : observers_) { |
164 observer.ReadingListWillMoveEntry(this, | 297 observer.ReadingListWillMoveEntry( |
165 std::distance(read_.begin(), result)); | 298 this, std::distance(read_->begin(), result), true); |
166 } | 299 } |
167 | 300 |
168 unread_.insert(unread_.begin(), std::move(*result)); | 301 result->MarkEntryUpdated(); |
169 read_.erase(result); | 302 if (storage_layer_) { |
| 303 storage_layer_->SaveEntry(*result, false); |
| 304 } |
170 | 305 |
171 if (storage_layer_ && !IsPerformingBatchUpdates()) { | 306 unread_->insert(unread_->begin(), std::move(*result)); |
172 storage_layer_->SavePersistentUnreadList(read_); | 307 read_->erase(result); |
173 storage_layer_->SavePersistentReadList(unread_); | 308 |
174 } | |
175 for (ReadingListModelObserver& observer : observers_) { | 309 for (ReadingListModelObserver& observer : observers_) { |
176 observer.ReadingListDidApplyChanges(this); | 310 observer.ReadingListDidApplyChanges(this); |
177 } | 311 } |
178 } | 312 } |
179 | 313 |
180 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { | 314 void ReadingListModelImpl::MarkReadByURL(const GURL& url) { |
| 315 DCHECK(CalledOnValidThread()); |
181 DCHECK(loaded()); | 316 DCHECK(loaded()); |
182 ReadingListEntry entry(url, std::string()); | 317 ReadingListEntry entry(url, std::string()); |
183 auto result = std::find(unread_.begin(), unread_.end(), entry); | 318 auto result = std::find(unread_->begin(), unread_->end(), entry); |
184 if (result == unread_.end()) | 319 if (result == unread_->end()) |
185 return; | 320 return; |
186 | 321 |
187 for (auto& observer : observers_) { | 322 for (auto& observer : observers_) |
188 observer.ReadingListWillMoveEntry(this, | 323 observer.ReadingListWillMoveEntry( |
189 std::distance(unread_.begin(), result)); | 324 this, std::distance(unread_->begin(), result), false); |
| 325 |
| 326 result->MarkEntryUpdated(); |
| 327 if (storage_layer_) { |
| 328 storage_layer_->SaveEntry(*result, true); |
190 } | 329 } |
191 | 330 |
192 read_.insert(read_.begin(), std::move(*result)); | 331 read_->insert(read_->begin(), std::move(*result)); |
193 unread_.erase(result); | 332 unread_->erase(result); |
194 | 333 |
195 if (storage_layer_ && !IsPerformingBatchUpdates()) { | |
196 storage_layer_->SavePersistentUnreadList(unread_); | |
197 storage_layer_->SavePersistentReadList(read_); | |
198 } | |
199 for (auto& observer : observers_) | 334 for (auto& observer : observers_) |
200 observer.ReadingListDidApplyChanges(this); | 335 observer.ReadingListDidApplyChanges(this); |
201 } | 336 } |
202 | 337 |
203 void ReadingListModelImpl::SetEntryTitle(const GURL& url, | 338 void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
204 const std::string& title) { | 339 const std::string& title) { |
| 340 DCHECK(CalledOnValidThread()); |
205 DCHECK(loaded()); | 341 DCHECK(loaded()); |
206 const ReadingListEntry entry(url, std::string()); | 342 const ReadingListEntry entry(url, std::string()); |
207 | 343 |
208 auto result = std::find(unread_.begin(), unread_.end(), entry); | 344 auto result = std::find(unread_->begin(), unread_->end(), entry); |
209 if (result != unread_.end()) { | 345 if (result != unread_->end()) { |
210 for (auto& observer : observers_) { | 346 for (auto& observer : observers_) |
211 observer.ReadingListWillUpdateUnreadEntry( | 347 observer.ReadingListWillUpdateUnreadEntry( |
212 this, std::distance(unread_.begin(), result)); | 348 this, std::distance(unread_->begin(), result)); |
| 349 result->SetTitle(title); |
| 350 |
| 351 if (storage_layer_) { |
| 352 storage_layer_->SaveEntry(*result, false); |
213 } | 353 } |
214 result->SetTitle(title); | |
215 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
216 storage_layer_->SavePersistentUnreadList(unread_); | |
217 for (auto& observer : observers_) | 354 for (auto& observer : observers_) |
218 observer.ReadingListDidApplyChanges(this); | 355 observer.ReadingListDidApplyChanges(this); |
219 return; | 356 return; |
220 } | 357 } |
221 | 358 |
222 result = std::find(read_.begin(), read_.end(), entry); | 359 result = std::find(read_->begin(), read_->end(), entry); |
223 if (result != read_.end()) { | 360 if (result != read_->end()) { |
224 for (auto& observer : observers_) { | 361 for (auto& observer : observers_) |
225 observer.ReadingListWillUpdateReadEntry( | 362 observer.ReadingListWillUpdateReadEntry( |
226 this, std::distance(read_.begin(), result)); | 363 this, std::distance(read_->begin(), result)); |
| 364 result->SetTitle(title); |
| 365 if (storage_layer_) { |
| 366 storage_layer_->SaveEntry(*result, true); |
227 } | 367 } |
228 result->SetTitle(title); | |
229 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
230 storage_layer_->SavePersistentReadList(read_); | |
231 for (auto& observer : observers_) | 368 for (auto& observer : observers_) |
232 observer.ReadingListDidApplyChanges(this); | 369 observer.ReadingListDidApplyChanges(this); |
233 return; | 370 return; |
234 } | 371 } |
235 } | 372 } |
236 | 373 |
237 void ReadingListModelImpl::SetEntryDistilledPath( | 374 void ReadingListModelImpl::SetEntryDistilledPath( |
238 const GURL& url, | 375 const GURL& url, |
239 const base::FilePath& distilled_path) { | 376 const base::FilePath& distilled_path) { |
| 377 DCHECK(CalledOnValidThread()); |
240 DCHECK(loaded()); | 378 DCHECK(loaded()); |
241 const ReadingListEntry entry(url, std::string()); | 379 const ReadingListEntry entry(url, std::string()); |
242 | 380 |
243 auto result = std::find(unread_.begin(), unread_.end(), entry); | 381 auto result = std::find(unread_->begin(), unread_->end(), entry); |
244 if (result != unread_.end()) { | 382 if (result != unread_->end()) { |
245 for (auto& observer : observers_) { | 383 for (auto& observer : observers_) |
246 observer.ReadingListWillUpdateUnreadEntry( | 384 observer.ReadingListWillUpdateUnreadEntry( |
247 this, std::distance(unread_.begin(), result)); | 385 this, std::distance(unread_->begin(), result)); |
| 386 result->SetDistilledPath(distilled_path); |
| 387 if (storage_layer_) { |
| 388 storage_layer_->SaveEntry(*result, false); |
248 } | 389 } |
249 result->SetDistilledPath(distilled_path); | |
250 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
251 storage_layer_->SavePersistentUnreadList(unread_); | |
252 for (auto& observer : observers_) | 390 for (auto& observer : observers_) |
253 observer.ReadingListDidApplyChanges(this); | 391 observer.ReadingListDidApplyChanges(this); |
254 return; | 392 return; |
255 } | 393 } |
256 | 394 |
257 result = std::find(read_.begin(), read_.end(), entry); | 395 result = std::find(read_->begin(), read_->end(), entry); |
258 if (result != read_.end()) { | 396 if (result != read_->end()) { |
259 for (auto& observer : observers_) { | 397 for (auto& observer : observers_) |
260 observer.ReadingListWillUpdateReadEntry( | 398 observer.ReadingListWillUpdateReadEntry( |
261 this, std::distance(read_.begin(), result)); | 399 this, std::distance(read_->begin(), result)); |
| 400 result->SetDistilledPath(distilled_path); |
| 401 if (storage_layer_) { |
| 402 storage_layer_->SaveEntry(*result, true); |
262 } | 403 } |
263 result->SetDistilledPath(distilled_path); | |
264 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
265 storage_layer_->SavePersistentReadList(read_); | |
266 for (auto& observer : observers_) | 404 for (auto& observer : observers_) |
267 observer.ReadingListDidApplyChanges(this); | 405 observer.ReadingListDidApplyChanges(this); |
268 return; | 406 return; |
269 } | 407 } |
270 } | 408 } |
271 | 409 |
272 void ReadingListModelImpl::SetEntryDistilledState( | 410 void ReadingListModelImpl::SetEntryDistilledState( |
273 const GURL& url, | 411 const GURL& url, |
274 ReadingListEntry::DistillationState state) { | 412 ReadingListEntry::DistillationState state) { |
| 413 DCHECK(CalledOnValidThread()); |
275 DCHECK(loaded()); | 414 DCHECK(loaded()); |
276 const ReadingListEntry entry(url, std::string()); | 415 const ReadingListEntry entry(url, std::string()); |
277 | 416 |
278 auto result = std::find(unread_.begin(), unread_.end(), entry); | 417 auto result = std::find(unread_->begin(), unread_->end(), entry); |
279 if (result != unread_.end()) { | 418 if (result != unread_->end()) { |
280 for (auto& observer : observers_) { | 419 for (auto& observer : observers_) |
281 observer.ReadingListWillUpdateUnreadEntry( | 420 observer.ReadingListWillUpdateUnreadEntry( |
282 this, std::distance(unread_.begin(), result)); | 421 this, std::distance(unread_->begin(), result)); |
| 422 result->SetDistilledState(state); |
| 423 if (storage_layer_) { |
| 424 storage_layer_->SaveEntry(*result, false); |
283 } | 425 } |
284 result->SetDistilledState(state); | |
285 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
286 storage_layer_->SavePersistentUnreadList(unread_); | |
287 for (auto& observer : observers_) | 426 for (auto& observer : observers_) |
288 observer.ReadingListDidApplyChanges(this); | 427 observer.ReadingListDidApplyChanges(this); |
289 return; | 428 return; |
290 } | 429 } |
291 | 430 |
292 result = std::find(read_.begin(), read_.end(), entry); | 431 result = std::find(read_->begin(), read_->end(), entry); |
293 if (result != read_.end()) { | 432 if (result != read_->end()) { |
294 for (auto& observer : observers_) { | 433 for (auto& observer : observers_) |
295 observer.ReadingListWillUpdateReadEntry( | 434 observer.ReadingListWillUpdateReadEntry( |
296 this, std::distance(read_.begin(), result)); | 435 this, std::distance(read_->begin(), result)); |
| 436 result->SetDistilledState(state); |
| 437 if (storage_layer_) { |
| 438 storage_layer_->SaveEntry(*result, true); |
297 } | 439 } |
298 result->SetDistilledState(state); | |
299 if (storage_layer_ && !IsPerformingBatchUpdates()) | |
300 storage_layer_->SavePersistentReadList(read_); | |
301 for (auto& observer : observers_) | 440 for (auto& observer : observers_) |
302 observer.ReadingListDidApplyChanges(this); | 441 observer.ReadingListDidApplyChanges(this); |
303 return; | 442 return; |
304 } | 443 } |
305 }; | 444 }; |
306 | 445 |
307 void ReadingListModelImpl::EndBatchUpdates() { | 446 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> |
308 ReadingListModel::EndBatchUpdates(); | 447 ReadingListModelImpl::CreateBatchToken() { |
309 if (IsPerformingBatchUpdates() || !storage_layer_) { | 448 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>( |
310 return; | 449 this); |
| 450 } |
| 451 |
| 452 ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| 453 ScopedReadingListBatchUpdate(ReadingListModelImpl* model) |
| 454 : ReadingListModel::ScopedReadingListBatchUpdate:: |
| 455 ScopedReadingListBatchUpdate(model) { |
| 456 if (model->StorageLayer()) { |
| 457 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); |
311 } | 458 } |
312 storage_layer_->SavePersistentUnreadList(unread_); | 459 } |
313 storage_layer_->SavePersistentReadList(read_); | 460 |
314 SetPersistentHasUnseen(has_unseen_); | 461 ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| 462 ~ScopedReadingListBatchUpdate() { |
| 463 storage_token_.reset(); |
| 464 } |
| 465 |
| 466 void ReadingListModelImpl::LeavingBatchUpdates() { |
| 467 DCHECK(CalledOnValidThread()); |
| 468 if (storage_layer_) { |
| 469 SetPersistentHasUnseen(has_unseen_); |
| 470 SortEntries(); |
| 471 } |
| 472 ReadingListModel::LeavingBatchUpdates(); |
| 473 } |
| 474 |
| 475 void ReadingListModelImpl::EnteringBatchUpdates() { |
| 476 DCHECK(CalledOnValidThread()); |
| 477 ReadingListModel::EnteringBatchUpdates(); |
315 } | 478 } |
316 | 479 |
317 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { | 480 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { |
| 481 DCHECK(CalledOnValidThread()); |
318 if (!pref_service_) { | 482 if (!pref_service_) { |
319 return; | 483 return; |
320 } | 484 } |
321 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, | 485 pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, |
322 has_unseen); | 486 has_unseen); |
323 } | 487 } |
324 | 488 |
325 bool ReadingListModelImpl::GetPersistentHasUnseen() { | 489 bool ReadingListModelImpl::GetPersistentHasUnseen() { |
| 490 DCHECK(CalledOnValidThread()); |
326 if (!pref_service_) { | 491 if (!pref_service_) { |
327 return false; | 492 return false; |
328 } | 493 } |
329 return pref_service_->GetBoolean( | 494 return pref_service_->GetBoolean( |
330 reading_list::prefs::kReadingListHasUnseenEntries); | 495 reading_list::prefs::kReadingListHasUnseenEntries); |
331 } | 496 } |
| 497 |
| 498 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { |
| 499 DCHECK(loaded()); |
| 500 if (!storage_layer_) |
| 501 return nullptr; |
| 502 return storage_layer_->GetModelTypeSyncBridge(); |
| 503 } |
| 504 |
| 505 void ReadingListModelImpl::SortEntries() { |
| 506 DCHECK(CalledOnValidThread()); |
| 507 DCHECK(loaded()); |
| 508 std::sort(read_->begin(), read_->end(), |
| 509 ReadingListEntry::CompareEntryUpdateTime); |
| 510 std::sort(unread_->begin(), unread_->end(), |
| 511 ReadingListEntry::CompareEntryUpdateTime); |
| 512 } |
| 513 |
| 514 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() { |
| 515 return storage_layer_.get(); |
| 516 } |
OLD | NEW |