Chromium Code Reviews| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "components/reading_list/ios/proto/reading_list.pb.h" | 10 #include "components/reading_list/ios/proto/reading_list.pb.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 | 224 |
| 225 if (!existing_entry) { | 225 if (!existing_entry) { |
| 226 // This entry is new. Add it to the store and model. | 226 // This entry is new. Add it to the store and model. |
| 227 // Convert to local store format and write to store. | 227 // Convert to local store format and write to store. |
| 228 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = | 228 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = |
| 229 entry->AsReadingListLocal(); | 229 entry->AsReadingListLocal(); |
| 230 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); | 230 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); |
| 231 | 231 |
| 232 // Notify model about updated entry. | 232 // Notify model about updated entry. |
| 233 delegate_->SyncAddEntry(std::move(entry)); | 233 delegate_->SyncAddEntry(std::move(entry)); |
| 234 } else if (existing_entry->UpdateTime() < entry->UpdateTime()) { | 234 } else { |
| 235 // The entry from sync is more recent. | 235 // The entry from sync is more recent. |
|
gambard
2016/12/06 17:02:22
Update comment
Olivier
2016/12/06 17:16:21
Done.
| |
| 236 // Merge the local data to it and store it. | 236 // Merge the local data to it and store it. |
| 237 ReadingListEntry* merged_entry = | 237 ReadingListEntry* merged_entry = |
| 238 delegate_->SyncMergeEntry(std::move(entry)); | 238 delegate_->SyncMergeEntry(std::move(entry)); |
| 239 | 239 |
| 240 // Write to the store. | 240 // Write to the store. |
| 241 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = | 241 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = |
| 242 merged_entry->AsReadingListLocal(); | 242 merged_entry->AsReadingListLocal(); |
| 243 batch_->WriteData(entry->URL().spec(), | 243 batch_->WriteData(entry->URL().spec(), |
| 244 entry_local_pb->SerializeAsString()); | 244 entry_local_pb->SerializeAsString()); |
| 245 | 245 |
| 246 // Send to sync | 246 // Send to sync |
| 247 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = | 247 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = |
| 248 merged_entry->AsReadingListSpecifics(); | 248 merged_entry->AsReadingListSpecifics(); |
| 249 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); | |
| 249 auto entity_data = base::MakeUnique<syncer::EntityData>(); | 250 auto entity_data = base::MakeUnique<syncer::EntityData>(); |
| 250 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; | 251 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; |
| 251 entity_data->non_unique_name = entry_sync_pb->entry_id(); | 252 entity_data->non_unique_name = entry_sync_pb->entry_id(); |
| 252 | 253 |
| 253 // TODO(crbug.com/666232): Investigate if there is a risk of sync | 254 // TODO(crbug.com/666232): Investigate if there is a risk of sync |
| 254 // ping-pong. | 255 // ping-pong. |
| 255 change_processor()->Put(entry_sync_pb->entry_id(), std::move(entity_data), | 256 change_processor()->Put(entry_sync_pb->entry_id(), std::move(entity_data), |
| 256 metadata_change_list.get()); | 257 metadata_change_list.get()); |
| 257 | 258 |
| 258 } else { | |
| 259 // The entry from sync is out of date. | |
| 260 // Send back the local more recent entry. | |
| 261 // No need to update | |
| 262 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_pb = | |
| 263 existing_entry->AsReadingListSpecifics(); | |
| 264 auto entity_data = base::MakeUnique<syncer::EntityData>(); | |
| 265 *(entity_data->specifics.mutable_reading_list()) = *entry_pb; | |
| 266 entity_data->non_unique_name = entry_pb->entry_id(); | |
| 267 | |
| 268 change_processor()->Put(entry_pb->entry_id(), std::move(entity_data), | |
| 269 metadata_change_list.get()); | |
| 270 } | 259 } |
| 271 } | 260 } |
| 272 | 261 |
| 273 // Commit local only entries to server. | 262 // Commit local only entries to server. |
| 274 for (const auto& url : model_->Keys()) { | 263 for (const auto& url : model_->Keys()) { |
| 275 const ReadingListEntry* entry = model_->GetEntryByURL(url); | 264 const ReadingListEntry* entry = model_->GetEntryByURL(url); |
| 276 if (synced_entries.count(url.spec())) { | 265 if (synced_entries.count(url.spec())) { |
| 277 // Entry already exists and has been merged above. | 266 // Entry already exists and has been merged above. |
| 278 continue; | 267 continue; |
| 279 } | 268 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 | 313 |
| 325 if (!existing_entry) { | 314 if (!existing_entry) { |
| 326 // This entry is new. Add it to the store and model. | 315 // This entry is new. Add it to the store and model. |
| 327 // Convert to local store format and write to store. | 316 // Convert to local store format and write to store. |
| 328 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = | 317 std::unique_ptr<reading_list::ReadingListLocal> entry_pb = |
| 329 entry->AsReadingListLocal(); | 318 entry->AsReadingListLocal(); |
| 330 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); | 319 batch_->WriteData(entry->URL().spec(), entry_pb->SerializeAsString()); |
| 331 | 320 |
| 332 // Notify model about updated entry. | 321 // Notify model about updated entry. |
| 333 delegate_->SyncAddEntry(std::move(entry)); | 322 delegate_->SyncAddEntry(std::move(entry)); |
| 334 } else if (existing_entry->UpdateTime() < entry->UpdateTime()) { | 323 } else { |
| 335 // The entry from sync is more recent. | 324 // The entry from sync is more recent. |
|
gambard
2016/12/06 17:02:22
Update comment
Olivier
2016/12/06 17:16:21
Done.
| |
| 336 // Merge the local data to it and store it. | 325 // Merge the local data to it and store it. |
| 337 ReadingListEntry* merged_entry = | 326 ReadingListEntry* merged_entry = |
| 338 delegate_->SyncMergeEntry(std::move(entry)); | 327 delegate_->SyncMergeEntry(std::move(entry)); |
| 339 | 328 |
| 340 // Write to the store. | 329 // Write to the store. |
| 341 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = | 330 std::unique_ptr<reading_list::ReadingListLocal> entry_local_pb = |
| 342 merged_entry->AsReadingListLocal(); | 331 merged_entry->AsReadingListLocal(); |
| 343 batch_->WriteData(merged_entry->URL().spec(), | 332 batch_->WriteData(merged_entry->URL().spec(), |
| 344 entry_local_pb->SerializeAsString()); | 333 entry_local_pb->SerializeAsString()); |
| 345 | 334 |
| 346 // Send to sync | 335 // Send to sync |
| 347 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = | 336 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_sync_pb = |
| 348 merged_entry->AsReadingListSpecifics(); | 337 merged_entry->AsReadingListSpecifics(); |
| 338 DCHECK(CompareEntriesForSync(specifics, *entry_sync_pb)); | |
| 349 auto entity_data = base::MakeUnique<syncer::EntityData>(); | 339 auto entity_data = base::MakeUnique<syncer::EntityData>(); |
| 350 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; | 340 *(entity_data->specifics.mutable_reading_list()) = *entry_sync_pb; |
| 351 entity_data->non_unique_name = entry_sync_pb->entry_id(); | 341 entity_data->non_unique_name = entry_sync_pb->entry_id(); |
| 352 | 342 |
| 353 // TODO(crbug.com/666232): Investigate if there is a risk of sync | 343 // TODO(crbug.com/666232): Investigate if there is a risk of sync |
| 354 // ping-pong. | 344 // ping-pong. |
| 355 change_processor()->Put(entry_sync_pb->entry_id(), | 345 change_processor()->Put(entry_sync_pb->entry_id(), |
| 356 std::move(entity_data), | 346 std::move(entity_data), |
| 357 metadata_change_list.get()); | 347 metadata_change_list.get()); |
| 358 | 348 |
| 359 } else { | |
| 360 // The entry from sync is out of date. | |
| 361 // Send back the local more recent entry. | |
| 362 // No need to update | |
| 363 std::unique_ptr<sync_pb::ReadingListSpecifics> entry_pb = | |
| 364 existing_entry->AsReadingListSpecifics(); | |
| 365 auto entity_data = base::MakeUnique<syncer::EntityData>(); | |
| 366 *(entity_data->specifics.mutable_reading_list()) = *entry_pb; | |
| 367 entity_data->non_unique_name = entry_pb->entry_id(); | |
| 368 | |
| 369 change_processor()->Put(entry_pb->entry_id(), std::move(entity_data), | |
| 370 metadata_change_list.get()); | |
| 371 } | 349 } |
| 372 } | 350 } |
| 373 } | 351 } |
| 374 | 352 |
| 375 batch_->TransferMetadataChanges(std::move(metadata_change_list)); | 353 batch_->TransferMetadataChanges(std::move(metadata_change_list)); |
| 376 return syncer::SyncError(); | 354 return syncer::SyncError(); |
| 377 } | 355 } |
| 378 | 356 |
| 379 void ReadingListStore::GetData(StorageKeyList storage_keys, | 357 void ReadingListStore::GetData(StorageKeyList storage_keys, |
| 380 DataCallback callback) { | 358 DataCallback callback) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 // called once when first encountering a remote entity. Local changes will | 410 // called once when first encountering a remote entity. Local changes will |
| 433 // provide their storage keys directly to Put instead of using this method. | 411 // provide their storage keys directly to Put instead of using this method. |
| 434 // Theoretically this function doesn't need to be stable across multiple calls | 412 // Theoretically this function doesn't need to be stable across multiple calls |
| 435 // on the same or different clients, but to keep things simple, it probably | 413 // on the same or different clients, but to keep things simple, it probably |
| 436 // should be. | 414 // should be. |
| 437 std::string ReadingListStore::GetStorageKey( | 415 std::string ReadingListStore::GetStorageKey( |
| 438 const syncer::EntityData& entity_data) { | 416 const syncer::EntityData& entity_data) { |
| 439 DCHECK(CalledOnValidThread()); | 417 DCHECK(CalledOnValidThread()); |
| 440 return entity_data.specifics.reading_list().entry_id(); | 418 return entity_data.specifics.reading_list().entry_id(); |
| 441 } | 419 } |
| 420 | |
| 421 bool ReadingListStore::CompareEntriesForSync( | |
| 422 const sync_pb::ReadingListSpecifics& lhs, | |
| 423 const sync_pb::ReadingListSpecifics& rhs) { | |
| 424 DCHECK(lhs.entry_id() == rhs.entry_id()); | |
| 425 DCHECK(lhs.has_update_time_us()); | |
| 426 DCHECK(rhs.has_update_time_us()); | |
| 427 DCHECK(lhs.has_creation_time_us()); | |
| 428 DCHECK(rhs.has_creation_time_us()); | |
| 429 DCHECK(lhs.has_url()); | |
| 430 DCHECK(rhs.has_url()); | |
| 431 DCHECK(lhs.has_title()); | |
| 432 DCHECK(rhs.has_title()); | |
| 433 DCHECK(lhs.has_status()); | |
| 434 DCHECK(rhs.has_status()); | |
| 435 if (lhs.update_time_us() < rhs.update_time_us()) { | |
| 436 // The entry is more recent, so it can be submitted to sync. | |
|
gambard
2016/12/06 17:02:22
"The entry" here and below is not specific enough.
Olivier
2016/12/06 17:16:21
Done.
| |
| 437 return true; | |
| 438 } | |
| 439 if (lhs.update_time_us() > rhs.update_time_us()) { | |
| 440 // The entry is older, so it cannot be submitted to sync. | |
| 441 return false; | |
| 442 } | |
| 443 | |
| 444 if (lhs.url() != rhs.url() || lhs.title() != rhs.title() || | |
|
gambard
2016/12/06 17:02:22
Not sure the check on "url()" is necessary here.
Olivier
2016/12/06 17:16:21
As far as sync is concerned, the key is entry_id.
| |
| 445 lhs.creation_time_us() != rhs.creation_time_us() || | |
| 446 lhs.update_time_us() != rhs.update_time_us()) { | |
|
gambard
2016/12/06 17:02:22
Actually I don't understand this condition.
If the
Olivier
2016/12/06 17:16:21
This method ensures that you send correct data to
| |
| 447 // A modification should not be submitted to the server without a change to | |
| 448 // update_time. | |
| 449 return false; | |
| 450 } | |
| 451 if (lhs.status() == sync_pb::ReadingListSpecifics::UNSEEN) { | |
| 452 // An entry can always be marked SEEN on a device. | |
| 453 return true; | |
| 454 } | |
| 455 if (lhs.status() != rhs.status()) { | |
|
gambard
2016/12/06 17:02:22
Maybe add a comment for this?
Olivier
2016/12/06 17:16:21
Done.
| |
| 456 return false; | |
| 457 } | |
| 458 // All cases should be handled. Entries must be the same. | |
| 459 DCHECK(lhs.SerializeAsString() == rhs.SerializeAsString()); | |
| 460 return true; | |
| 461 } | |
| OLD | NEW |