Chromium Code Reviews| Index: ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| diff --git a/ios/chrome/browser/reading_list/reading_list_model_impl.cc b/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| index 1066206e65d581c687a5e366dfc55b1008cc2f4d..5101a262af3df3e69b5327932fbcda0636552273 100644 |
| --- a/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| +++ b/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| @@ -4,76 +4,122 @@ |
| #include "ios/chrome/browser/reading_list/reading_list_model_impl.h" |
| +#include "base/bind.h" |
| +#include "base/logging.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "components/prefs/pref_service.h" |
| #include "ios/chrome/browser/reading_list/reading_list_model_storage.h" |
| +#include "ios/chrome/browser/reading_list/reading_list_pref_names.h" |
| +#include "ios/web/public/web_thread.h" |
| #include "url/gurl.h" |
| -ReadingListModelImpl::ReadingListModelImpl() : ReadingListModelImpl(NULL) {} |
| +ReadingListModelImpl::ReadingListModelImpl() |
| + : ReadingListModelImpl(NULL, NULL) {} |
| ReadingListModelImpl::ReadingListModelImpl( |
| - std::unique_ptr<ReadingListModelStorage> storage) |
| - : hasUnseen_(false) { |
| + std::unique_ptr<ReadingListModelStorage> storage, |
| + PrefService* pref_service) |
| + : pref_service_(pref_service), |
| + has_unseen_(false), |
| + loaded_(false), |
| + weak_ptr_factory_(this) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| if (storage) { |
| - storageLayer_ = std::move(storage); |
| - read_ = storageLayer_->LoadPersistentReadList(); |
| - unread_ = storageLayer_->LoadPersistentUnreadList(); |
| - hasUnseen_ = storageLayer_->LoadPersistentHasUnseen(); |
| + storage_layer_ = std::move(storage); |
| + storage_layer_->SetReadingListModel(this); |
| + } else { |
| + loaded_ = true; |
| + read_ = base::MakeUnique<ReadingListEntries>(); |
| + unread_ = base::MakeUnique<ReadingListEntries>(); |
| } |
| - loaded_ = true; |
| + has_unseen_ = LoadPersistentHasUnseen(); |
| } |
| ReadingListModelImpl::~ReadingListModelImpl() {} |
| +void ReadingListModelImpl::ModelLoaded( |
| + std::unique_ptr<ReadingListEntries> unread, |
| + std::unique_ptr<ReadingListEntries> read) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + read_ = std::move(read); |
| + unread_ = std::move(unread); |
| + SortEntries(); |
| + loaded_ = true; |
| + for (auto& observer : observers_) |
| + observer.ReadingListModelLoaded(this); |
| +} |
| + |
| void ReadingListModelImpl::Shutdown() { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| for (auto& observer : observers_) |
| observer.ReadingListModelBeingDeleted(this); |
| loaded_ = false; |
| } |
| bool ReadingListModelImpl::loaded() const { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| return loaded_; |
| } |
| size_t ReadingListModelImpl::unread_size() const { |
| - DCHECK(loaded()); |
| - return unread_.size(); |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + if (!loaded()) |
| + return 0; |
| + return unread_->size(); |
| } |
| size_t ReadingListModelImpl::read_size() const { |
| - DCHECK(loaded()); |
| - return read_.size(); |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + if (!loaded()) |
| + return 0; |
| + return read_->size(); |
| } |
| bool ReadingListModelImpl::HasUnseenEntries() const { |
| - DCHECK(loaded()); |
| - return unread_size() && hasUnseen_; |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + if (!loaded()) |
| + return false; |
| + return unread_size() && has_unseen_; |
| } |
| void ReadingListModelImpl::ResetUnseenEntries() { |
| DCHECK(loaded()); |
| - hasUnseen_ = false; |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentHasUnseen(false); |
| + has_unseen_ = false; |
| + if (!IsPerformingBatchUpdates()) |
| + SavePersistentHasUnseen(false); |
| } |
| const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( |
| size_t index) const { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| - return unread_[index]; |
| + return unread_->at(index); |
| } |
| const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( |
| size_t index) const { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| - return read_[index]; |
| + return read_->at(index); |
| } |
| const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( |
| const GURL& gurl) const { |
| DCHECK(loaded()); |
| + bool read; |
| + return GetMutableEntryFromURL(gurl, read); |
| +} |
| + |
| +ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( |
| + const GURL& gurl, |
| + 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.
|
| + DCHECK(loaded()); |
| ReadingListEntry entry(gurl, std::string()); |
| - auto it = std::find(read_.begin(), read_.end(), entry); |
| - if (it == read_.end()) { |
| - it = std::find(unread_.begin(), unread_.end(), entry); |
| - if (it == unread_.end()) |
| + auto it = std::find(read_->begin(), read_->end(), entry); |
| + read = true; |
| + if (it == read_->end()) { |
| + it = std::find(unread_->begin(), unread_->end(), entry); |
| + read = false; |
| + if (it == unread_->end()) |
| return nullptr; |
| } |
| return &(*it); |
| @@ -82,8 +128,10 @@ const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( |
| bool ReadingListModelImpl::CallbackEntryURL( |
| const GURL& url, |
| base::Callback<void(const ReadingListEntry&)> callback) const { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| - const ReadingListEntry* entry = GetEntryFromURL(url); |
| + bool read; |
| + const ReadingListEntry* entry = GetMutableEntryFromURL(url, read); |
| if (entry) { |
| callback.Run(*entry); |
| return true; |
| @@ -91,33 +139,118 @@ bool ReadingListModelImpl::CallbackEntryURL( |
| return false; |
| } |
| +bool ReadingListModelImpl::CallbackEntryReadStatusURL( |
| + const GURL& url, |
| + base::Callback<void(const ReadingListEntry&, bool read)> callback) const { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + DCHECK(loaded()); |
| + bool read; |
| + const ReadingListEntry* entry = GetMutableEntryFromURL(url, read); |
| + if (entry) { |
| + callback.Run(*entry, read); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +void ReadingListModelImpl::SyncAddEntry(std::unique_ptr<ReadingListEntry> entry, |
| + bool read) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + DCHECK(loaded()); |
| + 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.
|
| + ReadingListEntry* existing_entry = |
| + GetMutableEntryFromURL(entry->URL(), is_entry_read); |
| + if (!existing_entry) { |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*entry, read, true); |
| + } |
| + if (read) { |
| + for (auto& observer : observers_) |
| + observer.ReadingListWillAddReadEntry(this, *entry); |
| + read_->insert(read_->begin(), std::move(*entry)); |
| + } else { |
| + for (auto& observer : observers_) |
| + observer.ReadingListWillAddUnreadEntry(this, *entry); |
| + has_unseen_ = true; |
| + SavePersistentHasUnseen(true); |
| + unread_->insert(unread_->begin(), std::move(*entry)); |
| + } |
| + for (auto& observer : observers_) |
| + 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
|
| + return; |
| + } |
| + |
| + if (existing_entry->UpdateTime() > entry->UpdateTime()) { |
| + // Existing entry is newer thatn sync one. Do not update it. |
| + return; |
| + } |
| + |
| + // Merge local data in new entry. |
| + entry->MergeLocalStateFrom(*existing_entry); |
| + |
| + if (is_entry_read) { |
| + 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
|
| + if (result != read_->end()) { |
| + read_->erase(result); |
|
skym
2016/11/01 18:27:25
If |is_entry_read| == |read|, then updating the ex
|
| + } |
| + } else { |
| + auto result = std::find(unread_->begin(), unread_->end(), *existing_entry); |
| + if (result != unread_->end()) { |
| + unread_->erase(result); |
| + } |
| + } |
| + |
| + if (storage_layer_) { |
| + 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
|
| + } |
| + |
| + if (read) { |
| + read_->push_back(std::move(*entry)); |
| + } else { |
| + unread_->push_back(std::move(*entry)); |
| + } |
| +} |
| + |
| +void ReadingListModelImpl::SyncRemoveEntry(const GURL& gurl) { |
| + RemoveEntryByUrlImpl(gurl, true); |
| +} |
| + |
| void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { |
| + RemoveEntryByUrlImpl(url, false); |
| +} |
| + |
| +void ReadingListModelImpl::RemoveEntryByUrlImpl(const GURL& url, |
| + bool from_sync) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| const ReadingListEntry entry(url, std::string()); |
| - auto result = std::find(unread_.begin(), unread_.end(), entry); |
| - if (result != unread_.end()) { |
| - for (auto& observer : observers_) { |
| + auto result = std::find(unread_->begin(), unread_->end(), entry); |
| + if (result != unread_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillRemoveUnreadEntry( |
| - this, std::distance(unread_.begin(), result)); |
| + this, std::distance(unread_->begin(), result)); |
| + |
| + if (storage_layer_) { |
| + storage_layer_->RemoveEntry(*result, from_sync); |
| } |
| - unread_.erase(result); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| + unread_->erase(result); |
| + |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| - for (auto& observer : observers_) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillRemoveReadEntry( |
| - this, std::distance(read_.begin(), result)); |
| + this, std::distance(read_->begin(), result)); |
| + if (storage_layer_) { |
| + storage_layer_->RemoveEntry(*result, from_sync); |
| } |
| - read_.erase(result); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentReadList(read_); |
| + read_->erase(result); |
| + |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| @@ -127,97 +260,103 @@ void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { |
| const ReadingListEntry& ReadingListModelImpl::AddEntry( |
| const GURL& url, |
| const std::string& title) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| RemoveEntryByUrl(url); |
| ReadingListEntry entry(url, title); |
| for (auto& observer : observers_) |
| observer.ReadingListWillAddUnreadEntry(this, entry); |
| - unread_.insert(unread_.begin(), std::move(entry)); |
| - hasUnseen_ = true; |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) { |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| - storageLayer_->SavePersistentHasUnseen(true); |
| + has_unseen_ = true; |
| + SavePersistentHasUnseen(true); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(entry, false, false); |
| } |
| + unread_->insert(unread_->begin(), std::move(entry)); |
| + |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| - return *unread_.begin(); |
| + return *unread_->begin(); |
| } |
| void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { |
| DCHECK(loaded()); |
| ReadingListEntry entry(url, std::string()); |
| - auto result = std::find(read_.begin(), read_.end(), entry); |
| - if (result == read_.end()) |
| + auto result = std::find(read_->begin(), read_->end(), entry); |
| + if (result == read_->end()) |
| return; |
| for (ReadingListModelObserver& observer : observers_) { |
| observer.ReadingListWillMoveEntry(this, |
| - std::distance(read_.begin(), result)); |
| + std::distance(read_->begin(), result)); |
| } |
| - unread_.insert(unread_.begin(), std::move(*result)); |
| - read_.erase(result); |
| - |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) { |
| - storageLayer_->SavePersistentUnreadList(read_); |
| - storageLayer_->SavePersistentReadList(unread_); |
| + result->MarkEntryUpdated(); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, false, false); |
| } |
| + |
| + unread_->insert(unread_->begin(), std::move(*result)); |
| + read_->erase(result); |
| + |
| for (ReadingListModelObserver& observer : observers_) { |
| observer.ReadingListDidApplyChanges(this); |
| } |
| } |
| void ReadingListModelImpl::MarkReadByURL(const GURL& url) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| ReadingListEntry entry(url, std::string()); |
| - auto result = std::find(unread_.begin(), unread_.end(), entry); |
| - if (result == unread_.end()) |
| + auto result = std::find(unread_->begin(), unread_->end(), entry); |
| + if (result == unread_->end()) |
| return; |
| - for (auto& observer : observers_) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillMoveEntry(this, |
| - std::distance(unread_.begin(), result)); |
| + std::distance(unread_->begin(), result)); |
| + |
| + result->MarkEntryUpdated(); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true, false); |
| } |
| - read_.insert(read_.begin(), std::move(*result)); |
| - unread_.erase(result); |
| + read_->insert(read_->begin(), std::move(*result)); |
| + unread_->erase(result); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) { |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| - storageLayer_->SavePersistentReadList(read_); |
| - } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| } |
| void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
| const std::string& title) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| const ReadingListEntry entry(url, std::string()); |
| - auto result = std::find(unread_.begin(), unread_.end(), entry); |
| - if (result != unread_.end()) { |
| - for (auto& observer : observers_) { |
| + auto result = std::find(unread_->begin(), unread_->end(), entry); |
| + if (result != unread_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillUpdateUnreadEntry( |
| - this, std::distance(unread_.begin(), result)); |
| - } |
| + this, std::distance(unread_->begin(), result)); |
| result->SetTitle(title); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| + |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, false, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| - for (auto& observer : observers_) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillUpdateReadEntry( |
| - this, std::distance(read_.begin(), result)); |
| - } |
| + this, std::distance(read_->begin(), result)); |
| result->SetTitle(title); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentReadList(read_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| @@ -226,32 +365,33 @@ void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
| void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, |
| const GURL& distilled_url) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| const ReadingListEntry entry(url, std::string()); |
| - auto result = std::find(unread_.begin(), unread_.end(), entry); |
| - if (result != unread_.end()) { |
| - for (auto& observer : observers_) { |
| + auto result = std::find(unread_->begin(), unread_->end(), entry); |
| + if (result != unread_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillUpdateUnreadEntry( |
| - this, std::distance(unread_.begin(), result)); |
| - } |
| + this, std::distance(unread_->begin(), result)); |
| result->SetDistilledURL(distilled_url); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, false, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| - for (auto& observer : observers_) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillUpdateReadEntry( |
| - this, std::distance(read_.begin(), result)); |
| - } |
| + this, std::distance(read_->begin(), result)); |
| result->SetDistilledURL(distilled_url); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentReadList(read_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| @@ -261,44 +401,82 @@ void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, |
| void ReadingListModelImpl::SetEntryDistilledState( |
| const GURL& url, |
| ReadingListEntry::DistillationState state) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| DCHECK(loaded()); |
| const ReadingListEntry entry(url, std::string()); |
| - auto result = std::find(unread_.begin(), unread_.end(), entry); |
| - if (result != unread_.end()) { |
| - for (auto& observer : observers_) { |
| + auto result = std::find(unread_->begin(), unread_->end(), entry); |
| + if (result != unread_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillUpdateUnreadEntry( |
| - this, std::distance(unread_.begin(), result)); |
| - } |
| + this, std::distance(unread_->begin(), result)); |
| result->SetDistilledState(state); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, false, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| - for (auto& observer : observers_) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| + for (auto& observer : observers_) |
| observer.ReadingListWillUpdateReadEntry( |
| - this, std::distance(read_.begin(), result)); |
| - } |
| + this, std::distance(read_->begin(), result)); |
| result->SetDistilledState(state); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentReadList(read_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| } |
| }; |
| -void ReadingListModelImpl::EndBatchUpdates() { |
| - ReadingListModel::EndBatchUpdates(); |
| - if (IsPerformingBatchUpdates() || !storageLayer_) { |
| +void ReadingListModelImpl::LeavingBatchUpdates() { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + ReadingListModel::LeavingBatchUpdates(); |
| + if (storage_layer_) { |
| + SavePersistentHasUnseen(has_unseen_); |
| + storage_layer_->CommitTransaction(); |
| + SortEntries(); |
| + } |
| +} |
| + |
| +void ReadingListModelImpl::EnteringBatchUpdates() { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + if (storage_layer_) { |
| + storage_layer_->BeginTransaction(); |
| + } |
| + ReadingListModel::EnteringBatchUpdates(); |
| +} |
| + |
| +void ReadingListModelImpl::SavePersistentHasUnseen(bool has_unseen) { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + if (!pref_service_) { |
| return; |
| } |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| - storageLayer_->SavePersistentReadList(read_); |
| - storageLayer_->SavePersistentHasUnseen(hasUnseen_); |
| + pref_service_->SetBoolean(reading_list::prefs::kReadingListHasUnseenEntries, |
| + has_unseen); |
| +} |
| + |
| +bool ReadingListModelImpl::LoadPersistentHasUnseen() { |
| + DCHECK_CURRENTLY_ON(web::WebThread::UI); |
| + if (!pref_service_) { |
| + return false; |
| + } |
| + return pref_service_->GetBoolean( |
| + reading_list::prefs::kReadingListHasUnseenEntries); |
| +} |
| + |
| +syncer::ModelTypeService* ReadingListModelImpl::GetModelTypeService() { |
| + return storage_layer_->GetModelTypeService(); |
| +} |
| + |
| +void ReadingListModelImpl::SortEntries() { |
| + std::sort(read_->begin(), read_->end(), |
| + ReadingListEntry::CompareEntryUpdateTime); |
| + std::sort(unread_->begin(), unread_->end(), |
| + ReadingListEntry::CompareEntryUpdateTime); |
| } |