| 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 "components/reading_list/ios/reading_list_store.h" | 5 #include "components/reading_list/ios/reading_list_store.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/time/clock.h" |
| 13 #include "components/reading_list/ios/proto/reading_list.pb.h" | 14 #include "components/reading_list/ios/proto/reading_list.pb.h" |
| 14 #include "components/reading_list/ios/reading_list_model_impl.h" | 15 #include "components/reading_list/ios/reading_list_model_impl.h" |
| 15 #include "components/sync/model/entity_change.h" | 16 #include "components/sync/model/entity_change.h" |
| 16 #include "components/sync/model/metadata_batch.h" | 17 #include "components/sync/model/metadata_batch.h" |
| 17 #include "components/sync/model/metadata_change_list.h" | 18 #include "components/sync/model/metadata_change_list.h" |
| 18 #include "components/sync/model/model_type_change_processor.h" | 19 #include "components/sync/model/model_type_change_processor.h" |
| 19 #include "components/sync/model/mutable_data_batch.h" | 20 #include "components/sync/model/mutable_data_batch.h" |
| 20 #include "components/sync/model_impl/accumulating_metadata_change_list.h" | 21 #include "components/sync/model_impl/accumulating_metadata_change_list.h" |
| 21 #include "components/sync/protocol/model_type_state.pb.h" | 22 #include "components/sync/protocol/model_type_state.pb.h" |
| 22 | 23 |
| 23 ReadingListStore::ReadingListStore( | 24 ReadingListStore::ReadingListStore( |
| 24 StoreFactoryFunction create_store_callback, | 25 StoreFactoryFunction create_store_callback, |
| 25 const ChangeProcessorFactory& change_processor_factory) | 26 const ChangeProcessorFactory& change_processor_factory) |
| 26 : ReadingListModelStorage(change_processor_factory, syncer::READING_LIST), | 27 : ReadingListModelStorage(change_processor_factory, syncer::READING_LIST), |
| 27 create_store_callback_(create_store_callback), | 28 create_store_callback_(create_store_callback), |
| 28 pending_transaction_count_(0) {} | 29 pending_transaction_count_(0) {} |
| 29 | 30 |
| 30 ReadingListStore::~ReadingListStore() { | 31 ReadingListStore::~ReadingListStore() { |
| 31 DCHECK_EQ(0, pending_transaction_count_); | 32 DCHECK_EQ(0, pending_transaction_count_); |
| 32 } | 33 } |
| 33 | 34 |
| 34 void ReadingListStore::SetReadingListModel(ReadingListModel* model, | 35 void ReadingListStore::SetReadingListModel(ReadingListModel* model, |
| 35 ReadingListStoreDelegate* delegate) { | 36 ReadingListStoreDelegate* delegate, |
| 37 base::Clock* clock) { |
| 36 DCHECK(CalledOnValidThread()); | 38 DCHECK(CalledOnValidThread()); |
| 37 model_ = model; | 39 model_ = model; |
| 38 delegate_ = delegate; | 40 delegate_ = delegate; |
| 41 clock_ = clock; |
| 39 create_store_callback_.Run( | 42 create_store_callback_.Run( |
| 40 base::Bind(&ReadingListStore::OnStoreCreated, base::AsWeakPtr(this))); | 43 base::Bind(&ReadingListStore::OnStoreCreated, base::AsWeakPtr(this))); |
| 41 } | 44 } |
| 42 | 45 |
| 43 std::unique_ptr<ReadingListModelStorage::ScopedBatchUpdate> | 46 std::unique_ptr<ReadingListModelStorage::ScopedBatchUpdate> |
| 44 ReadingListStore::EnsureBatchCreated() { | 47 ReadingListStore::EnsureBatchCreated() { |
| 45 return base::WrapUnique<ReadingListModelStorage::ScopedBatchUpdate>( | 48 return base::WrapUnique<ReadingListModelStorage::ScopedBatchUpdate>( |
| 46 new ScopedBatchUpdate(this)); | 49 new ScopedBatchUpdate(this)); |
| 47 } | 50 } |
| 48 | 51 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 72 base::Bind(&ReadingListStore::OnDatabaseSave, base::AsWeakPtr(this))); | 75 base::Bind(&ReadingListStore::OnDatabaseSave, base::AsWeakPtr(this))); |
| 73 batch_.reset(); | 76 batch_.reset(); |
| 74 } | 77 } |
| 75 } | 78 } |
| 76 | 79 |
| 77 void ReadingListStore::SaveEntry(const ReadingListEntry& entry) { | 80 void ReadingListStore::SaveEntry(const ReadingListEntry& entry) { |
| 78 DCHECK(CalledOnValidThread()); | 81 DCHECK(CalledOnValidThread()); |
| 79 auto token = EnsureBatchCreated(); | 82 auto token = EnsureBatchCreated(); |
| 80 | 83 |
| 81 std::unique_ptr<reading_list::ReadingListLocal> pb_entry = | 84 std::unique_ptr<reading_list::ReadingListLocal> pb_entry = |
| 82 entry.AsReadingListLocal(); | 85 entry.AsReadingListLocal(clock_->Now()); |
| 83 | 86 |
| 84 batch_->WriteData(entry.URL().spec(), pb_entry->SerializeAsString()); | 87 batch_->WriteData(entry.URL().spec(), pb_entry->SerializeAsString()); |
| 85 | 88 |
| 86 if (!change_processor()->IsTrackingMetadata()) { | 89 if (!change_processor()->IsTrackingMetadata()) { |
| 87 return; | 90 return; |
| 88 } | 91 } |
| 89 std::unique_ptr<sync_pb::ReadingListSpecifics> pb_entry_sync = | 92 std::unique_ptr<sync_pb::ReadingListSpecifics> pb_entry_sync = |
| 90 entry.AsReadingListSpecifics(); | 93 entry.AsReadingListSpecifics(); |
| 91 | 94 |
| 92 std::unique_ptr<syncer::MetadataChangeList> metadata_change_list = | 95 std::unique_ptr<syncer::MetadataChangeList> metadata_change_list = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 | 133 |
| 131 for (const syncer::ModelTypeStore::Record& r : *entries.get()) { | 134 for (const syncer::ModelTypeStore::Record& r : *entries.get()) { |
| 132 reading_list::ReadingListLocal proto; | 135 reading_list::ReadingListLocal proto; |
| 133 if (!proto.ParseFromString(r.value)) { | 136 if (!proto.ParseFromString(r.value)) { |
| 134 continue; | 137 continue; |
| 135 // TODO(skym, crbug.com/582460): Handle unrecoverable initialization | 138 // TODO(skym, crbug.com/582460): Handle unrecoverable initialization |
| 136 // failure. | 139 // failure. |
| 137 } | 140 } |
| 138 | 141 |
| 139 std::unique_ptr<ReadingListEntry> entry( | 142 std::unique_ptr<ReadingListEntry> entry( |
| 140 ReadingListEntry::FromReadingListLocal(proto)); | 143 ReadingListEntry::FromReadingListLocal(proto, clock_->Now())); |
| 141 if (!entry) { | 144 if (!entry) { |
| 142 continue; | 145 continue; |
| 143 } | 146 } |
| 144 GURL url = entry->URL(); | 147 GURL url = entry->URL(); |
| 145 DCHECK(!loaded_entries->count(url)); | 148 DCHECK(!loaded_entries->count(url)); |
| 146 loaded_entries->insert(std::make_pair(url, std::move(*entry))); | 149 loaded_entries->insert(std::make_pair(url, std::move(*entry))); |
| 147 } | 150 } |
| 148 | 151 |
| 149 delegate_->StoreLoaded(std::move(loaded_entries)); | 152 delegate_->StoreLoaded(std::move(loaded_entries)); |
| 150 | 153 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> | 214 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> |
| 212 model_batch_updates = model_->BeginBatchUpdates(); | 215 model_batch_updates = model_->BeginBatchUpdates(); |
| 213 | 216 |
| 214 // Merge sync to local data. | 217 // Merge sync to local data. |
| 215 for (const auto& kv : entity_data_map) { | 218 for (const auto& kv : entity_data_map) { |
| 216 synced_entries.insert(kv.first); | 219 synced_entries.insert(kv.first); |
| 217 const sync_pb::ReadingListSpecifics& specifics = | 220 const sync_pb::ReadingListSpecifics& specifics = |
| 218 kv.second.value().specifics.reading_list(); | 221 kv.second.value().specifics.reading_list(); |
| 219 // Deserialize entry. | 222 // Deserialize entry. |
| 220 std::unique_ptr<ReadingListEntry> entry( | 223 std::unique_ptr<ReadingListEntry> entry( |
| 221 ReadingListEntry::FromReadingListSpecifics(specifics)); | 224 ReadingListEntry::FromReadingListSpecifics(specifics, clock_->Now())); |
| 222 | 225 |
| 223 const ReadingListEntry* existing_entry = | 226 const ReadingListEntry* existing_entry = |
| 224 model_->GetEntryByURL(entry->URL()); | 227 model_->GetEntryByURL(entry->URL()); |
| 225 | 228 |
| 226 if (!existing_entry) { | 229 if (!existing_entry) { |
| 227 // This entry is new. Add it to the store and model. | 230 // This entry is new. Add it to the store and model. |
| 228 // Convert to local store format and write to store. | 231 // Convert to local store format and write to store. |
| 229 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = | 232 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = |
| 230 entry->AsReadingListLocal(); | 233 entry->AsReadingListLocal(clock_->Now()); |
| 231 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); | 234 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); |
| 232 | 235 |
| 233 // Notify model about updated entry. | 236 // Notify model about updated entry. |
| 234 delegate_->SyncAddEntry(std::move(entry)); | 237 delegate_->SyncAddEntry(std::move(entry)); |
| 235 } else { | 238 } else { |
| 236 // Merge the local data and the sync data and store the result. | 239 // Merge the local data and the sync data and store the result. |
| 237 ReadingListEntry* merged_entry = | 240 ReadingListEntry* merged_entry = |
| 238 delegate_->SyncMergeEntry(std::move(entry)); | 241 delegate_->SyncMergeEntry(std::move(entry)); |
| 239 | 242 |
| 240 // Write to the store. | 243 // Write to the store. |
| 241 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = | 244 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = |
| 242 merged_entry->AsReadingListLocal(); | 245 merged_entry->AsReadingListLocal(clock_->Now()); |
| 243 batch_->WriteData(merged_entry->URL().spec(), | 246 batch_->WriteData(merged_entry->URL().spec(), |
| 244 entry_local_pb->SerializeAsString()); | 247 entry_local_pb->SerializeAsString()); |
| 245 | 248 |
| 246 // Send to sync | 249 // Send to sync |
| 247 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = | 250 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = |
| 248 merged_entry->AsReadingListSpecifics(); | 251 merged_entry->AsReadingListSpecifics(); |
| 249 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); | 252 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); |
| 250 auto entity_data = base::MakeUnique<syncer::EntityData>(); | 253 auto entity_data = base::MakeUnique<syncer::EntityData>(); |
| 251 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; | 254 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; |
| 252 entity_data->non_unique_name = entry_sync_pb->entry_id(); | 255 entity_data->non_unique_name = entry_sync_pb->entry_id(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 for (syncer::EntityChange& change : entity_changes) { | 301 for (syncer::EntityChange& change : entity_changes) { |
| 299 if (change.type() == syncer::EntityChange::ACTION_DELETE) { | 302 if (change.type() == syncer::EntityChange::ACTION_DELETE) { |
| 300 batch_->DeleteData(change.storage_key()); | 303 batch_->DeleteData(change.storage_key()); |
| 301 // Need to notify model that entry is deleted. | 304 // Need to notify model that entry is deleted. |
| 302 delegate_->SyncRemoveEntry(GURL(change.storage_key())); | 305 delegate_->SyncRemoveEntry(GURL(change.storage_key())); |
| 303 } else { | 306 } else { |
| 304 // Deserialize entry. | 307 // Deserialize entry. |
| 305 const sync_pb::ReadingListSpecifics& specifics = | 308 const sync_pb::ReadingListSpecifics& specifics = |
| 306 change.data().specifics.reading_list(); | 309 change.data().specifics.reading_list(); |
| 307 std::unique_ptr<ReadingListEntry> entry( | 310 std::unique_ptr<ReadingListEntry> entry( |
| 308 ReadingListEntry::FromReadingListSpecifics(specifics)); | 311 ReadingListEntry::FromReadingListSpecifics(specifics, clock_->Now())); |
| 309 | 312 |
| 310 const ReadingListEntry* existing_entry = | 313 const ReadingListEntry* existing_entry = |
| 311 model_->GetEntryByURL(entry->URL()); | 314 model_->GetEntryByURL(entry->URL()); |
| 312 | 315 |
| 313 if (!existing_entry) { | 316 if (!existing_entry) { |
| 314 // This entry is new. Add it to the store and model. | 317 // This entry is new. Add it to the store and model. |
| 315 // Convert to local store format and write to store. | 318 // Convert to local store format and write to store. |
| 316 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = | 319 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = |
| 317 entry->AsReadingListLocal(); | 320 entry->AsReadingListLocal(clock_->Now()); |
| 318 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); | 321 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); |
| 319 | 322 |
| 320 // Notify model about updated entry. | 323 // Notify model about updated entry. |
| 321 delegate_->SyncAddEntry(std::move(entry)); | 324 delegate_->SyncAddEntry(std::move(entry)); |
| 322 } else { | 325 } else { |
| 323 // Merge the local data and the sync data and store the result. | 326 // Merge the local data and the sync data and store the result. |
| 324 ReadingListEntry* merged_entry = | 327 ReadingListEntry* merged_entry = |
| 325 delegate_->SyncMergeEntry(std::move(entry)); | 328 delegate_->SyncMergeEntry(std::move(entry)); |
| 326 | 329 |
| 327 // Write to the store. | 330 // Write to the store. |
| 328 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = | 331 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = |
| 329 merged_entry->AsReadingListLocal(); | 332 merged_entry->AsReadingListLocal(clock_->Now()); |
| 330 batch_->WriteData(merged_entry->URL().spec(), | 333 batch_->WriteData(merged_entry->URL().spec(), |
| 331 entry_local_pb->SerializeAsString()); | 334 entry_local_pb->SerializeAsString()); |
| 332 | 335 |
| 333 // Send to sync | 336 // Send to sync |
| 334 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = | 337 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = |
| 335 merged_entry->AsReadingListSpecifics(); | 338 merged_entry->AsReadingListSpecifics(); |
| 336 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); | 339 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); |
| 337 auto entity_data = base::MakeUnique<syncer::EntityData>(); | 340 auto entity_data = base::MakeUnique<syncer::EntityData>(); |
| 338 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; | 341 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; |
| 339 entity_data->non_unique_name = entry_sync_pb->entry_id(); | 342 entity_data->non_unique_name = entry_sync_pb->entry_id(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 if (rhs.first_read_time_us() == 0 && lhs.first_read_time_us() != 0) { | 455 if (rhs.first_read_time_us() == 0 && lhs.first_read_time_us() != 0) { |
| 453 return false; | 456 return false; |
| 454 } | 457 } |
| 455 if (rhs.first_read_time_us() > lhs.first_read_time_us() && | 458 if (rhs.first_read_time_us() > lhs.first_read_time_us() && |
| 456 lhs.first_read_time_us() != 0) { | 459 lhs.first_read_time_us() != 0) { |
| 457 return false; | 460 return false; |
| 458 } | 461 } |
| 459 } | 462 } |
| 460 return true; | 463 return true; |
| 461 } | 464 } |
| OLD | NEW |