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 2012052a080ecee238c77bdf0ecb7630fb92dee2..20163c6341cf4301da2abf9b60ed50ed4479e270 100644 |
| --- a/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| +++ b/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| @@ -4,10 +4,15 @@ |
| #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 "base/strings/string_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/chrome/browser/reading_list/reading_list_store.h" |
| +#include "ios/web/public/web_thread.h" |
|
pavely
2016/11/14 07:45:33
ReadingListModelImpl interacts with store through
Olivier
2016/11/14 11:36:49
Done.
|
| #include "url/gurl.h" |
| ReadingListModelImpl::ReadingListModelImpl() |
| @@ -16,80 +21,126 @@ ReadingListModelImpl::ReadingListModelImpl() |
| ReadingListModelImpl::ReadingListModelImpl( |
| std::unique_ptr<ReadingListModelStorage> storage, |
| PrefService* pref_service) |
| - : pref_service_(pref_service), has_unseen_(false) { |
| + : pref_service_(pref_service), |
| + has_unseen_(false), |
| + loaded_(false), |
| + weak_ptr_factory_(this) { |
| + DCHECK(CalledOnValidThread()); |
| if (storage) { |
| storage_layer_ = std::move(storage); |
| - read_ = storage_layer_->LoadPersistentReadList(); |
| - unread_ = storage_layer_->LoadPersistentUnreadList(); |
| - has_unseen_ = GetPersistentHasUnseen(); |
| + storage_layer_->SetReadingListModel(this, this); |
| + } else { |
| + loaded_ = true; |
| + read_ = base::MakeUnique<ReadingListEntries>(); |
| + unread_ = base::MakeUnique<ReadingListEntries>(); |
| } |
| - loaded_ = true; |
| + has_unseen_ = GetPersistentHasUnseen(); |
| } |
| ReadingListModelImpl::~ReadingListModelImpl() {} |
| +void ReadingListModelImpl::StoreLoaded( |
| + std::unique_ptr<ReadingListEntries> unread, |
| + std::unique_ptr<ReadingListEntries> read) { |
| + DCHECK(CalledOnValidThread()); |
| + read_ = std::move(read); |
| + unread_ = std::move(unread); |
| + loaded_ = true; |
| + SortEntries(); |
| + for (auto& observer : observers_) |
| + observer.ReadingListModelLoaded(this); |
| +} |
| + |
| void ReadingListModelImpl::Shutdown() { |
| + DCHECK(CalledOnValidThread()); |
| for (auto& observer : observers_) |
| observer.ReadingListModelBeingDeleted(this); |
| loaded_ = false; |
| } |
| bool ReadingListModelImpl::loaded() const { |
| + DCHECK(CalledOnValidThread()); |
| return loaded_; |
| } |
| size_t ReadingListModelImpl::unread_size() const { |
| - DCHECK(loaded()); |
| - return unread_.size(); |
| + DCHECK(CalledOnValidThread()); |
| + if (!loaded()) |
| + return 0; |
| + return unread_->size(); |
| } |
| size_t ReadingListModelImpl::read_size() const { |
| - DCHECK(loaded()); |
| - return read_.size(); |
| + DCHECK(CalledOnValidThread()); |
| + if (!loaded()) |
| + return 0; |
| + return read_->size(); |
| } |
| bool ReadingListModelImpl::HasUnseenEntries() const { |
| - DCHECK(loaded()); |
| + DCHECK(CalledOnValidThread()); |
| + if (!loaded()) |
| + return false; |
| return unread_size() && has_unseen_; |
| } |
| void ReadingListModelImpl::ResetUnseenEntries() { |
| + DCHECK(CalledOnValidThread()); |
| DCHECK(loaded()); |
| has_unseen_ = false; |
| - if (storage_layer_ && !IsPerformingBatchUpdates()) |
| + if (!IsPerformingBatchUpdates()) |
| SetPersistentHasUnseen(false); |
| } |
| const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( |
| size_t index) const { |
| + DCHECK(CalledOnValidThread()); |
| DCHECK(loaded()); |
| - return unread_[index]; |
| + return unread_->at(index); |
| } |
| const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( |
| size_t index) const { |
| + DCHECK(CalledOnValidThread()); |
| DCHECK(loaded()); |
| - return read_[index]; |
| + return read_->at(index); |
| } |
| const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( |
| - const GURL& gurl) const { |
| + const GURL& gurl, |
| + bool* read) const { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(loaded()); |
| + return GetMutableEntryFromURL(gurl, read); |
| +} |
| + |
| +ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( |
| + const GURL& gurl, |
| + bool* read) const { |
| + DCHECK(CalledOnValidThread()); |
| DCHECK(loaded()); |
| + bool is_read; |
| 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); |
| + is_read = true; |
| + if (it == read_->end()) { |
| + it = std::find(unread_->begin(), unread_->end(), entry); |
| + is_read = false; |
| + if (it == unread_->end()) |
| return nullptr; |
| } |
| + if (read) { |
| + *read = is_read; |
| + } |
| return &(*it); |
| } |
| bool ReadingListModelImpl::CallbackEntryURL( |
| const GURL& url, |
| base::Callback<void(const ReadingListEntry&)> callback) const { |
| + DCHECK(CalledOnValidThread()); |
| DCHECK(loaded()); |
| - const ReadingListEntry* entry = GetEntryFromURL(url); |
| + const ReadingListEntry* entry = GetMutableEntryFromURL(url, nullptr); |
| if (entry) { |
| callback.Run(*entry); |
| return true; |
| @@ -97,38 +148,117 @@ bool ReadingListModelImpl::CallbackEntryURL( |
| return false; |
| } |
| +void ReadingListModelImpl::SyncAddEntry(std::unique_ptr<ReadingListEntry> entry, |
| + bool read) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(loaded()); |
| + bool is_existing_entry_read; |
| + ReadingListEntry* existing_entry = |
| + GetMutableEntryFromURL(entry->URL(), &is_existing_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; |
| + SetPersistentHasUnseen(true); |
| + unread_->insert(unread_->begin(), std::move(*entry)); |
| + } |
| + for (auto& observer : observers_) |
| + observer.ReadingListDidApplyChanges(this); |
| + return; |
| + } |
| + |
| + if (existing_entry->UpdateTime() > entry->UpdateTime()) { |
| + // Existing entry is newer than the sync one. Do not update it. |
| + return; |
| + } |
| + |
| + // Merge local data in new entry. |
| + entry->MergeLocalStateFrom(*existing_entry); |
| + |
| + if (is_existing_entry_read) { |
|
pavely
2016/11/14 07:45:33
Each branch of if statement can be factored out in
Olivier
2016/11/14 11:36:49
Done.
|
| + auto result = std::find(read_->begin(), read_->end(), *existing_entry); |
| + DCHECK(result != read_->end()); |
| + int index = std::distance(read_->begin(), result); |
| + for (auto& observer : observers_) |
| + observer.ReadingListWillMoveEntry(this, index, true); |
| + |
| + read_->erase(result); |
|
pavely
2016/11/14 07:45:33
Naive question... I'm just curious: With the rest
Olivier
2016/11/14 11:36:49
This follow the notifications in other models like
|
| + } else { |
| + auto result = std::find(unread_->begin(), unread_->end(), *existing_entry); |
| + DCHECK(result != unread_->end()); |
| + int index = std::distance(unread_->begin(), result); |
| + for (auto& observer : observers_) |
| + observer.ReadingListWillMoveEntry(this, index, false); |
| + |
| + unread_->erase(result); |
| + } |
| + |
| + if (storage_layer_) { |
|
pavely
2016/11/14 07:45:33
SyncAddEntry should be invoked from ReadingListSto
Olivier
2016/11/14 11:36:49
Done.
|
| + storage_layer_->SaveEntry(*entry, read, true); |
| + } |
| + |
| + if (read) { |
| + read_->push_back(std::move(*entry)); |
| + } else { |
| + unread_->push_back(std::move(*entry)); |
| + } |
| + for (auto& observer : observers_) |
| + observer.ReadingListDidApplyChanges(this); |
| +} |
| + |
| +void ReadingListModelImpl::SyncRemoveEntry(const GURL& gurl) { |
| + RemoveEntryByURLImpl(gurl, true); |
| +} |
| + |
| // Temporary method |
| void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { |
| return RemoveEntryByURL(url); |
| } |
| void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { |
| + RemoveEntryByURLImpl(url, false); |
| +} |
| + |
| +void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, |
| + bool from_sync) { |
| + DCHECK(CalledOnValidThread()); |
| 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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->SavePersistentReadList(read_); |
| + read_->erase(result); |
| + |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| @@ -138,6 +268,7 @@ void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { |
| const ReadingListEntry& ReadingListModelImpl::AddEntry( |
| const GURL& url, |
| const std::string& title) { |
| + DCHECK(CalledOnValidThread()); |
| DCHECK(loaded()); |
| RemoveEntryByURL(url); |
| @@ -147,92 +278,98 @@ const ReadingListEntry& ReadingListModelImpl::AddEntry( |
| ReadingListEntry entry(url, trimmedTitle); |
| for (auto& observer : observers_) |
| observer.ReadingListWillAddUnreadEntry(this, entry); |
| - unread_.insert(unread_.begin(), std::move(entry)); |
| has_unseen_ = true; |
| - if (storage_layer_ && !IsPerformingBatchUpdates()) { |
| - storage_layer_->SavePersistentUnreadList(unread_); |
| - SetPersistentHasUnseen(true); |
| + SetPersistentHasUnseen(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(CalledOnValidThread()); |
| 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)); |
| + observer.ReadingListWillMoveEntry( |
| + this, std::distance(read_->begin(), result), true); |
| } |
| - unread_.insert(unread_.begin(), std::move(*result)); |
| - read_.erase(result); |
| - |
| - if (storage_layer_ && !IsPerformingBatchUpdates()) { |
| - storage_layer_->SavePersistentUnreadList(read_); |
| - storage_layer_->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(CalledOnValidThread()); |
| 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_) { |
| - observer.ReadingListWillMoveEntry(this, |
| - std::distance(unread_.begin(), result)); |
| + for (auto& observer : observers_) |
| + observer.ReadingListWillMoveEntry( |
| + this, std::distance(unread_->begin(), result), false); |
| + |
| + 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 (storage_layer_ && !IsPerformingBatchUpdates()) { |
| - storage_layer_->SavePersistentUnreadList(unread_); |
| - storage_layer_->SavePersistentReadList(read_); |
| - } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| } |
| void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
|
pavely
2016/11/14 07:45:33
It is typical pattern for update functions in this
Olivier
2016/11/14 11:36:49
This is something we definitely want to do. We don
|
| const std::string& title) { |
| + DCHECK(CalledOnValidThread()); |
| 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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->SavePersistentReadList(read_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| @@ -241,32 +378,33 @@ void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
| void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, |
| const GURL& distilled_url) { |
| + DCHECK(CalledOnValidThread()); |
| 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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->SavePersistentReadList(read_); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true, false); |
| + } |
| for (auto& observer : observers_) |
| observer.ReadingListDidApplyChanges(this); |
| return; |
| @@ -276,49 +414,75 @@ void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, |
| void ReadingListModelImpl::SetEntryDistilledState( |
| const GURL& url, |
| ReadingListEntry::DistillationState state) { |
| + DCHECK(CalledOnValidThread()); |
| 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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->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 (storage_layer_ && !IsPerformingBatchUpdates()) |
| - storage_layer_->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() || !storage_layer_) { |
| - return; |
| +std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> |
| +ReadingListModelImpl::CreateBatchToken() { |
| + return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>( |
| + this); |
| +} |
| + |
| +ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| + ScopedReadingListBatchUpdate(ReadingListModelImpl* model) |
| + : ReadingListModel::ScopedReadingListBatchUpdate:: |
| + ScopedReadingListBatchUpdate(model) { |
| + if (model->StorageLayer()) { |
| + storage_token_ = model->StorageLayer()->EnsureBatchCreated(); |
| + } |
| +} |
| + |
| +ReadingListModelImpl::ScopedReadingListBatchUpdate:: |
| + ~ScopedReadingListBatchUpdate() { |
| + storage_token_.reset(); |
| +} |
| + |
| +void ReadingListModelImpl::LeavingBatchUpdates() { |
| + DCHECK(CalledOnValidThread()); |
| + if (storage_layer_) { |
| + SetPersistentHasUnseen(has_unseen_); |
| + SortEntries(); |
| } |
| - storage_layer_->SavePersistentUnreadList(unread_); |
| - storage_layer_->SavePersistentReadList(read_); |
| - SetPersistentHasUnseen(has_unseen_); |
| + ReadingListModel::LeavingBatchUpdates(); |
| +} |
| + |
| +void ReadingListModelImpl::EnteringBatchUpdates() { |
| + DCHECK(CalledOnValidThread()); |
| + ReadingListModel::EnteringBatchUpdates(); |
| } |
| void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { |
| + DCHECK(CalledOnValidThread()); |
| if (!pref_service_) { |
| return; |
| } |
| @@ -327,9 +491,30 @@ void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { |
| } |
| bool ReadingListModelImpl::GetPersistentHasUnseen() { |
| + DCHECK(CalledOnValidThread()); |
| if (!pref_service_) { |
| return false; |
| } |
| return pref_service_->GetBoolean( |
| reading_list::prefs::kReadingListHasUnseenEntries); |
| } |
| + |
| +syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { |
| + DCHECK(loaded()); |
| + if (!storage_layer_) |
| + return nullptr; |
| + return storage_layer_->GetModelTypeSyncBridge(); |
| +} |
| + |
| +void ReadingListModelImpl::SortEntries() { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(loaded()); |
| + std::sort(read_->begin(), read_->end(), |
| + ReadingListEntry::CompareEntryUpdateTime); |
| + std::sort(unread_->begin(), unread_->end(), |
| + ReadingListEntry::CompareEntryUpdateTime); |
| +} |
| + |
| +ReadingListModelStorage* ReadingListModelImpl::StorageLayer() { |
| + return storage_layer_.get(); |
| +} |