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 c3e068d65f0249a30a6ce1c36dbd381cdf56d260..cb89e472072681356c3bb158a2220c58c0e22431 100644 |
| --- a/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| +++ b/ios/chrome/browser/reading_list/reading_list_model_impl.cc |
| @@ -4,24 +4,43 @@ |
| #include "ios/chrome/browser/reading_list/reading_list_model_impl.h" |
| +#include "base/bind.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 "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) { |
| if (storage) { |
| - storageLayer_ = std::move(storage); |
| - read_ = storageLayer_->LoadPersistentReadList(); |
| - unread_ = storageLayer_->LoadPersistentUnreadList(); |
| - hasUnseen_ = storageLayer_->LoadPersistentHasUnseen(); |
| + storage_layer_ = std::move(storage); |
| + storage_layer_->SetReadingListModel(this); |
| + storage_layer_->LoadPersistentLists(); |
| + } else { |
| + loaded_ = true; |
| } |
| - loaded_ = true; |
| + has_unseen_ = LoadPersistentHasUnseen(); |
| } |
| ReadingListModelImpl::~ReadingListModelImpl() {} |
| +void ReadingListModelImpl::ModelLoaded( |
| + std::unique_ptr<ReadingListEntries> unread, |
| + std::unique_ptr<ReadingListEntries> read) { |
| + read_ = std::move(read); |
| + unread_ = std::move(unread); |
| + loaded_ = true; |
| + FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| + ReadingListModelLoaded(this)); |
| +} |
| + |
| void ReadingListModelImpl::Shutdown() { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListModelBeingDeleted(this)); |
| @@ -33,38 +52,41 @@ bool ReadingListModelImpl::loaded() const { |
| } |
| size_t ReadingListModelImpl::unread_size() const { |
| - DCHECK(loaded()); |
| - return unread_.size(); |
| + if (!loaded()) |
| + return 0; |
| + return unread_->size(); |
| } |
| size_t ReadingListModelImpl::read_size() const { |
| - DCHECK(loaded()); |
| - return read_.size(); |
| + if (!loaded()) |
| + return 0; |
| + return read_->size(); |
| } |
| bool ReadingListModelImpl::HasUnseenEntries() const { |
| - DCHECK(loaded()); |
| - return unread_size() && hasUnseen_; |
| + if (!loaded()) |
| + return false; |
| + return unread_size() && has_unseen_; |
|
jif-google
2016/09/27 16:39:03
At first glance it seems weird that "return unread
Olivier
2016/09/28 11:20:06
It is HasUnseenEntries, not HasUnreadEntries.
jif
2016/10/03 07:50:03
Acknowledged.
|
| } |
| void ReadingListModelImpl::ResetUnseenEntries() { |
| DCHECK(loaded()); |
| - hasUnseen_ = false; |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentHasUnseen(false); |
| + has_unseen_ = false; |
| + if (!IsPerformingBatchUpdates()) |
| + SavePersistentHasUnseen(false); |
| } |
| // Returns a specific entry. |
| const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( |
| size_t index) const { |
| DCHECK(loaded()); |
| - return unread_[index]; |
| + return unread_->at(index); |
| } |
| const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( |
| size_t index) const { |
| DCHECK(loaded()); |
| - return read_[index]; |
| + return read_->at(index); |
| } |
| bool ReadingListModelImpl::CallbackEntryURL( |
| @@ -72,14 +94,14 @@ bool ReadingListModelImpl::CallbackEntryURL( |
| base::Callback<void(const ReadingListEntry&)> callback) const { |
| DCHECK(loaded()); |
| ReadingListEntry entry(url, std::string()); |
| - auto resultUnread = std::find(unread_.begin(), unread_.end(), entry); |
| - if (resultUnread != unread_.end()) { |
| + auto resultUnread = std::find(unread_->begin(), unread_->end(), entry); |
| + if (resultUnread != unread_->end()) { |
| callback.Run(*resultUnread); |
| return true; |
| } |
| - auto resultRead = std::find(read_.begin(), read_.end(), entry); |
| - if (resultRead != read_.end()) { |
| + auto resultRead = std::find(read_->begin(), read_->end(), entry); |
| + if (resultRead != read_->end()) { |
| callback.Run(*resultRead); |
| return true; |
| } |
| @@ -90,27 +112,33 @@ void ReadingListModelImpl::RemoveEntryByUrl(const GURL& url) { |
| DCHECK(loaded()); |
| const 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()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListWillRemoveUnreadEntry( |
| - this, std::distance(unread_.begin(), result))); |
| - unread_.erase(result); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| + this, std::distance(unread_->begin(), result))); |
| + unread_->erase(result); |
| + |
| + if (storage_layer_) { |
| + storage_layer_->RemoveEntry(*result); |
| + } |
| + |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListWillRemoveReadEntry( |
| - this, std::distance(read_.begin(), result))); |
| - read_.erase(result); |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) |
| - storageLayer_->SavePersistentReadList(read_); |
| + this, std::distance(read_->begin(), result))); |
| + read_->erase(result); |
| + |
| + if (storage_layer_) { |
| + storage_layer_->RemoveEntry(*result); |
| + } |
| + |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| @@ -125,35 +153,38 @@ const ReadingListEntry& ReadingListModelImpl::AddEntry( |
| ReadingListEntry entry(url, title); |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListWillAddUnreadEntry(this, entry)); |
| - unread_.insert(unread_.begin(), std::move(entry)); |
| - hasUnseen_ = true; |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) { |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| - storageLayer_->SavePersistentHasUnseen(true); |
| + unread_->insert(unread_->begin(), std::move(entry)); |
| + has_unseen_ = true; |
| + SavePersistentHasUnseen(true); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(entry, false); |
| } |
| + |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| - return *unread_.begin(); |
| + return *unread_->begin(); |
| } |
| void ReadingListModelImpl::MarkReadByURL(const GURL& url) { |
| 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; |
| + storage_layer_->SaveEntry(entry, true); |
| FOR_EACH_OBSERVER( |
| ReadingListModelObserver, observers_, |
| - ReadingListWillMoveEntry(this, std::distance(unread_.begin(), result))); |
| + ReadingListWillMoveEntry(this, std::distance(unread_->begin(), result))); |
| - read_.insert(read_.begin(), std::move(*result)); |
| - unread_.erase(result); |
| - |
| - if (storageLayer_ && !IsPerformingBatchUpdates()) { |
| - storageLayer_->SavePersistentUnreadList(unread_); |
| - storageLayer_->SavePersistentReadList(read_); |
| + result->MarkEntryUpdated(); |
| + if (storage_layer_) { |
| + storage_layer_->SaveEntry(*result, true); |
| } |
| + |
| + read_->insert(read_->begin(), std::move(*result)); |
| + unread_->erase(result); |
| + |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| } |
| @@ -163,27 +194,30 @@ void ReadingListModelImpl::SetEntryTitle(const GURL& url, |
| DCHECK(loaded()); |
| const 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()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| 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); |
| + } |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| 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); |
| + } |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| @@ -195,27 +229,29 @@ void ReadingListModelImpl::SetEntryDistilledURL(const GURL& url, |
| DCHECK(loaded()); |
| const 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()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| 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); |
| + } |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| 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); |
| + } |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| @@ -228,39 +264,62 @@ void ReadingListModelImpl::SetEntryDistilledState( |
| DCHECK(loaded()); |
| const 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()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| 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); |
| + } |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| } |
| - result = std::find(read_.begin(), read_.end(), entry); |
| - if (result != read_.end()) { |
| + result = std::find(read_->begin(), read_->end(), entry); |
| + if (result != read_->end()) { |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| 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); |
| + } |
| FOR_EACH_OBSERVER(ReadingListModelObserver, observers_, |
| ReadingListDidApplyChanges(this)); |
| return; |
| } |
| }; |
| -void ReadingListModelImpl::EndBatchUpdates() { |
| - ReadingListModel::EndBatchUpdates(); |
| - if (IsPerformingBatchUpdates() || !storageLayer_) { |
| +void ReadingListModelImpl::LeavingBatchUpdates() { |
| + ReadingListModel::EnteringBatchUpdates(); |
| + if (storage_layer_) { |
| + SavePersistentHasUnseen(has_unseen_); |
| + storage_layer_->CommitTransaction(); |
| + } |
| +} |
| + |
| +void ReadingListModelImpl::EnteringBatchUpdates() { |
| + if (storage_layer_) { |
| + storage_layer_->BeginTransaction(); |
| + } |
| + ReadingListModel::EnteringBatchUpdates(); |
| +} |
| + |
| +void ReadingListModelImpl::SavePersistentHasUnseen(bool has_unseen) { |
| + 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() { |
| + if (!pref_service_) { |
| + return false; |
| + } |
| + return pref_service_->GetBoolean( |
| + reading_list::prefs::kReadingListHasUnseenEntries); |
| } |