Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: components/sync_driver/generic_change_processor.cc

Issue 265853004: Revert of Keep track of which attachments are referenced by which sync entries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/sync_driver/generic_change_processor.h" 5 #include "components/sync_driver/generic_change_processor.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "sync/api/sync_change.h" 10 #include "sync/api/sync_change.h"
(...skipping 18 matching lines...) Expand all
29 syncer::WriteNode* write_node) { 29 syncer::WriteNode* write_node) {
30 if (syncer::GetModelTypeFromSpecifics(entity_specifics) == 30 if (syncer::GetModelTypeFromSpecifics(entity_specifics) ==
31 syncer::PASSWORDS) { 31 syncer::PASSWORDS) {
32 write_node->SetPasswordSpecifics( 32 write_node->SetPasswordSpecifics(
33 entity_specifics.password().client_only_encrypted_data()); 33 entity_specifics.password().client_only_encrypted_data());
34 } else { 34 } else {
35 write_node->SetEntitySpecifics(entity_specifics); 35 write_node->SetEntitySpecifics(entity_specifics);
36 } 36 }
37 } 37 }
38 38
39 // Helper function to convert AttachmentId to AttachmentMetadataRecord.
40 sync_pb::AttachmentMetadataRecord AttachmentIdToRecord(
41 const syncer::AttachmentId& attachment_id) {
42 sync_pb::AttachmentMetadataRecord record;
43 *record.mutable_id() = attachment_id.GetProto();
44 return record;
45 }
46
47 // Replace |write_nodes|'s attachment ids with |attachment_ids|.
48 void SetAttachmentMetadata(const syncer::AttachmentIdList& attachment_ids,
49 syncer::WriteNode* write_node) {
50 DCHECK(write_node);
51 sync_pb::AttachmentMetadata attachment_metadata;
52 std::transform(
53 attachment_ids.begin(),
54 attachment_ids.end(),
55 RepeatedFieldBackInserter(attachment_metadata.mutable_record()),
56 AttachmentIdToRecord);
57 write_node->SetAttachmentMetadata(attachment_metadata);
58 }
59
60 syncer::SyncData BuildRemoteSyncData( 39 syncer::SyncData BuildRemoteSyncData(
61 int64 sync_id, 40 int64 sync_id,
62 const syncer::BaseNode& read_node, 41 const syncer::BaseNode& read_node,
63 const syncer::AttachmentServiceProxy& attachment_service_proxy) { 42 const syncer::AttachmentServiceProxy& attachment_service_proxy) {
64 const syncer::AttachmentIdList& attachment_ids = read_node.GetAttachmentIds(); 43 const syncer::AttachmentIdList& attachment_ids = read_node.GetAttachmentIds();
65 // Use the specifics of non-password datatypes directly (encryption has 44 // Use the specifics of non-password datatypes directly (encryption has
66 // already been handled). 45 // already been handled).
67 if (read_node.GetModelType() != syncer::PASSWORDS) { 46 if (read_node.GetModelType() != syncer::PASSWORDS) {
68 return syncer::SyncData::CreateRemoteData(sync_id, 47 return syncer::SyncData::CreateRemoteData(sync_id,
69 read_node.GetEntitySpecifics(), 48 read_node.GetEntitySpecifics(),
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 // Should have listed all the possible error cases above. 312 // Should have listed all the possible error cases above.
334 error.Reset(from_here, error_prefix + "unknown error", type); 313 error.Reset(from_here, error_prefix + "unknown error", type);
335 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, 314 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
336 error.message()); 315 error.message());
337 LOG(ERROR) << "Delete: Unknown error."; 316 LOG(ERROR) << "Delete: Unknown error.";
338 return error; 317 return error;
339 } 318 }
340 } 319 }
341 } 320 }
342 321
343 syncer::SyncError AttemptDelete(const syncer::SyncChange& change, 322 syncer::SyncError AttemptDelete(
344 syncer::ModelType type, 323 const syncer::SyncChange& change,
345 const std::string& type_str, 324 syncer::ModelType type,
346 syncer::WriteNode* node, 325 const std::string& type_str,
347 DataTypeErrorHandler* error_handler) { 326 syncer::WriteNode* node,
327 DataTypeErrorHandler* error_handler) {
348 DCHECK_EQ(change.change_type(), syncer::SyncChange::ACTION_DELETE); 328 DCHECK_EQ(change.change_type(), syncer::SyncChange::ACTION_DELETE);
349 if (change.sync_data().IsLocal()) { 329 if (change.sync_data().IsLocal()) {
350 const std::string& tag = syncer::SyncDataLocal(change.sync_data()).GetTag(); 330 const std::string& tag = syncer::SyncDataLocal(change.sync_data()).GetTag();
351 if (tag.empty()) { 331 if (tag.empty()) {
352 syncer::SyncError error( 332 syncer::SyncError error(
353 FROM_HERE, 333 FROM_HERE,
354 syncer::SyncError::DATATYPE_ERROR, 334 syncer::SyncError::DATATYPE_ERROR,
355 "Failed to delete " + type_str + " node. Local data, empty tag. " + 335 "Failed to delete " + type_str + " node. Local data, empty tag. " +
356 change.location().ToString(), 336 change.location().ToString(),
357 type); 337 type);
(...skipping 23 matching lines...) Expand all
381 type, error_handler); 361 type, error_handler);
382 } 362 }
383 } 363 }
384 if (IsActOnceDataType(type)) 364 if (IsActOnceDataType(type))
385 node->Drop(); 365 node->Drop();
386 else 366 else
387 node->Tombstone(); 367 node->Tombstone();
388 return syncer::SyncError(); 368 return syncer::SyncError();
389 } 369 }
390 370
391 // A callback invoked on completion of AttachmentService::StoreAttachment.
392 void IgnoreStoreResult(const syncer::AttachmentService::StoreResult&) {
393 // TODO(maniscalco): Here is where we're going to update the in-directory
394 // entry to indicate that the attachments have been successfully stored on
395 // disk. Why do we care? Because we might crash after persisting the
396 // directory to disk, but before we have persisted its attachments, leaving us
397 // with danging attachment ids. Having a flag that indicates we've stored the
398 // entry will allow us to detect and filter entries with dangling attachment
399 // ids (bug 368353).
400 }
401
402 void StoreAttachments(syncer::AttachmentService* attachment_service,
403 const syncer::AttachmentList& attachments) {
404 DCHECK(attachment_service);
405 syncer::AttachmentService::StoreCallback ignore_store_result =
406 base::Bind(&IgnoreStoreResult);
407 attachment_service->StoreAttachments(attachments, ignore_store_result);
408 }
409
410 } // namespace 371 } // namespace
411 372
412 syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( 373 syncer::SyncError GenericChangeProcessor::ProcessSyncChanges(
413 const tracked_objects::Location& from_here, 374 const tracked_objects::Location& from_here,
414 const syncer::SyncChangeList& list_of_changes) { 375 const syncer::SyncChangeList& list_of_changes) {
415 DCHECK(CalledOnValidThread()); 376 DCHECK(CalledOnValidThread());
416
417 // Keep track of brand new attachments so we can persist them on this device
418 // and upload them to the server.
419 syncer::AttachmentList new_attachments;
420
421 syncer::WriteTransaction trans(from_here, share_handle()); 377 syncer::WriteTransaction trans(from_here, share_handle());
422 378
423 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); 379 for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin();
424 iter != list_of_changes.end(); 380 iter != list_of_changes.end();
425 ++iter) { 381 ++iter) {
426 const syncer::SyncChange& change = *iter; 382 const syncer::SyncChange& change = *iter;
427 DCHECK_NE(change.sync_data().GetDataType(), syncer::UNSPECIFIED); 383 DCHECK_NE(change.sync_data().GetDataType(), syncer::UNSPECIFIED);
428 syncer::ModelType type = change.sync_data().GetDataType(); 384 syncer::ModelType type = change.sync_data().GetDataType();
429 std::string type_str = syncer::ModelTypeToString(type); 385 std::string type_str = syncer::ModelTypeToString(type);
430 syncer::WriteNode sync_node(&trans); 386 syncer::WriteNode sync_node(&trans);
431 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { 387 if (change.change_type() == syncer::SyncChange::ACTION_DELETE) {
432 syncer::SyncError error = 388 syncer::SyncError error =
433 AttemptDelete(change, type, type_str, &sync_node, error_handler()); 389 AttemptDelete(change, type, type_str, &sync_node, error_handler());
434 if (error.IsSet()) { 390 if (error.IsSet()) {
435 NOTREACHED(); 391 NOTREACHED();
436 return error; 392 return error;
437 } 393 }
394 attachment_service_->OnSyncDataDelete(change.sync_data());
438 if (merge_result_.get()) { 395 if (merge_result_.get()) {
439 merge_result_->set_num_items_deleted( 396 merge_result_->set_num_items_deleted(
440 merge_result_->num_items_deleted() + 1); 397 merge_result_->num_items_deleted() + 1);
441 } 398 }
442 } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { 399 } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) {
443 syncer::SyncError error = HandleActionAdd( 400 syncer::SyncError error =
444 change, type_str, type, trans, &sync_node, &new_attachments); 401 HandleActionAdd(change, type_str, type, trans, &sync_node);
445 if (error.IsSet()) { 402 if (error.IsSet()) {
446 return error; 403 return error;
447 } 404 }
448 } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) { 405 } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) {
449 syncer::SyncError error = HandleActionUpdate( 406 syncer::SyncError error =
450 change, type_str, type, trans, &sync_node, &new_attachments); 407 HandleActionUpdate(change, type_str, type, trans, &sync_node);
451 if (error.IsSet()) { 408 if (error.IsSet()) {
452 return error; 409 return error;
453 } 410 }
454 } else { 411 } else {
455 syncer::SyncError error( 412 syncer::SyncError error(
456 FROM_HERE, 413 FROM_HERE,
457 syncer::SyncError::DATATYPE_ERROR, 414 syncer::SyncError::DATATYPE_ERROR,
458 "Received unset SyncChange in the change processor, " + 415 "Received unset SyncChange in the change processor, " +
459 change.location().ToString(), 416 change.location().ToString(),
460 type); 417 type);
461 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 418 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
462 error.message()); 419 error.message());
463 NOTREACHED(); 420 NOTREACHED();
464 LOG(ERROR) << "Unset sync change."; 421 LOG(ERROR) << "Unset sync change.";
465 return error; 422 return error;
466 } 423 }
467 } 424 }
468
469 if (!new_attachments.empty()) {
470 StoreAttachments(attachment_service_.get(), new_attachments);
471 }
472
473 return syncer::SyncError(); 425 return syncer::SyncError();
474 } 426 }
475 427
476 // WARNING: this code is sensitive to compiler optimizations. Be careful 428 // WARNING: this code is sensitive to compiler optimizations. Be careful
477 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else 429 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else
478 // the compiler attempts to merge it with other calls, losing useful information 430 // the compiler attempts to merge it with other calls, losing useful information
479 // in breakpad uploads. 431 // in breakpad uploads.
480 syncer::SyncError GenericChangeProcessor::HandleActionAdd( 432 syncer::SyncError GenericChangeProcessor::HandleActionAdd(
481 const syncer::SyncChange& change, 433 const syncer::SyncChange& change,
482 const std::string& type_str, 434 const std::string& type_str,
483 const syncer::ModelType& type, 435 const syncer::ModelType& type,
484 const syncer::WriteTransaction& trans, 436 const syncer::WriteTransaction& trans,
485 syncer::WriteNode* sync_node, 437 syncer::WriteNode* sync_node) {
486 syncer::AttachmentList* new_attachments) {
487 // TODO(sync): Handle other types of creation (custom parents, folders, 438 // TODO(sync): Handle other types of creation (custom parents, folders,
488 // etc.). 439 // etc.).
489 syncer::ReadNode root_node(&trans); 440 syncer::ReadNode root_node(&trans);
490 const syncer::SyncDataLocal sync_data_local(change.sync_data());
491 if (root_node.InitByTagLookup(syncer::ModelTypeToRootTag( 441 if (root_node.InitByTagLookup(syncer::ModelTypeToRootTag(
492 sync_data_local.GetDataType())) != syncer::BaseNode::INIT_OK) { 442 change.sync_data().GetDataType())) != syncer::BaseNode::INIT_OK) {
493 syncer::SyncError error(FROM_HERE, 443 syncer::SyncError error(FROM_HERE,
494 syncer::SyncError::DATATYPE_ERROR, 444 syncer::SyncError::DATATYPE_ERROR,
495 "Failed to look up root node for type " + type_str, 445 "Failed to look up root node for type " + type_str,
496 type); 446 type);
497 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 447 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
498 error.message()); 448 error.message());
499 NOTREACHED(); 449 NOTREACHED();
500 LOG(ERROR) << "Create: no root node."; 450 LOG(ERROR) << "Create: no root node.";
501 return error; 451 return error;
502 } 452 }
503 syncer::WriteNode::InitUniqueByCreationResult result = 453 syncer::WriteNode::InitUniqueByCreationResult result =
504 sync_node->InitUniqueByCreation( 454 sync_node->InitUniqueByCreation(
505 sync_data_local.GetDataType(), root_node, sync_data_local.GetTag()); 455 change.sync_data().GetDataType(),
456 root_node,
457 syncer::SyncDataLocal(change.sync_data()).GetTag());
506 if (result != syncer::WriteNode::INIT_SUCCESS) { 458 if (result != syncer::WriteNode::INIT_SUCCESS) {
507 std::string error_prefix = "Failed to create " + type_str + " node: " + 459 std::string error_prefix = "Failed to create " + type_str + " node: " +
508 change.location().ToString() + ", "; 460 change.location().ToString() + ", ";
509 switch (result) { 461 switch (result) {
510 case syncer::WriteNode::INIT_FAILED_EMPTY_TAG: { 462 case syncer::WriteNode::INIT_FAILED_EMPTY_TAG: {
511 syncer::SyncError error; 463 syncer::SyncError error;
512 error.Reset(FROM_HERE, error_prefix + "empty tag", type); 464 error.Reset(FROM_HERE, error_prefix + "empty tag", type);
513 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 465 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
514 error.message()); 466 error.message());
515 LOG(ERROR) << "Create: Empty tag."; 467 LOG(ERROR) << "Create: Empty tag.";
(...skipping 28 matching lines...) Expand all
544 syncer::SyncError error; 496 syncer::SyncError error;
545 error.Reset(FROM_HERE, error_prefix + "unknown error", type); 497 error.Reset(FROM_HERE, error_prefix + "unknown error", type);
546 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 498 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
547 error.message()); 499 error.message());
548 LOG(ERROR) << "Create: Unknown error."; 500 LOG(ERROR) << "Create: Unknown error.";
549 return error; 501 return error;
550 } 502 }
551 } 503 }
552 } 504 }
553 sync_node->SetTitle(change.sync_data().GetTitle()); 505 sync_node->SetTitle(change.sync_data().GetTitle());
554 SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); 506 SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node);
555 507 attachment_service_->OnSyncDataAdd(change.sync_data());
556 syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds();
557 SetAttachmentMetadata(attachment_ids, sync_node);
558
559 // Return any newly added attachments.
560 const syncer::AttachmentList& local_attachments_for_upload =
561 sync_data_local.GetLocalAttachmentsForUpload();
562 new_attachments->insert(new_attachments->end(),
563 local_attachments_for_upload.begin(),
564 local_attachments_for_upload.end());
565
566 if (merge_result_.get()) { 508 if (merge_result_.get()) {
567 merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); 509 merge_result_->set_num_items_added(merge_result_->num_items_added() + 1);
568 } 510 }
569 return syncer::SyncError(); 511 return syncer::SyncError();
570 } 512 }
571 // WARNING: this code is sensitive to compiler optimizations. Be careful 513 // WARNING: this code is sensitive to compiler optimizations. Be careful
572 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else 514 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else
573 // the compiler attempts to merge it with other calls, losing useful information 515 // the compiler attempts to merge it with other calls, losing useful information
574 // in breakpad uploads. 516 // in breakpad uploads.
575 syncer::SyncError GenericChangeProcessor::HandleActionUpdate( 517 syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
576 const syncer::SyncChange& change, 518 const syncer::SyncChange& change,
577 const std::string& type_str, 519 const std::string& type_str,
578 const syncer::ModelType& type, 520 const syncer::ModelType& type,
579 const syncer::WriteTransaction& trans, 521 const syncer::WriteTransaction& trans,
580 syncer::WriteNode* sync_node, 522 syncer::WriteNode* sync_node) {
581 syncer::AttachmentList* new_attachments) {
582 // TODO(zea): consider having this logic for all possible changes? 523 // TODO(zea): consider having this logic for all possible changes?
583
584 const syncer::SyncDataLocal sync_data_local(change.sync_data());
585 syncer::BaseNode::InitByLookupResult result = 524 syncer::BaseNode::InitByLookupResult result =
586 sync_node->InitByClientTagLookup(sync_data_local.GetDataType(), 525 sync_node->InitByClientTagLookup(
587 sync_data_local.GetTag()); 526 change.sync_data().GetDataType(),
527 syncer::SyncDataLocal(change.sync_data()).GetTag());
588 if (result != syncer::BaseNode::INIT_OK) { 528 if (result != syncer::BaseNode::INIT_OK) {
589 std::string error_prefix = "Failed to load " + type_str + " node. " + 529 std::string error_prefix = "Failed to load " + type_str + " node. " +
590 change.location().ToString() + ", "; 530 change.location().ToString() + ", ";
591 if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) { 531 if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) {
592 syncer::SyncError error; 532 syncer::SyncError error;
593 error.Reset(FROM_HERE, error_prefix + "empty tag", type); 533 error.Reset(FROM_HERE, error_prefix + "empty tag", type);
594 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 534 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
595 error.message()); 535 error.message());
596 LOG(ERROR) << "Update: Empty tag."; 536 LOG(ERROR) << "Update: Empty tag.";
597 return error; 537 return error;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 type); 599 type);
660 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 600 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
661 error.message()); 601 error.message());
662 LOG(ERROR) << "Update: encr case 4."; 602 LOG(ERROR) << "Update: encr case 4.";
663 return error; 603 return error;
664 } 604 }
665 } 605 }
666 } 606 }
667 607
668 sync_node->SetTitle(change.sync_data().GetTitle()); 608 sync_node->SetTitle(change.sync_data().GetTitle());
669 SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); 609 SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node);
670 SetAttachmentMetadata(sync_data_local.GetAttachmentIds(), sync_node); 610 attachment_service_->OnSyncDataUpdate(sync_node->GetAttachmentIds(),
671 611 change.sync_data());
672 // Return any newly added attachments.
673 const syncer::AttachmentList& local_attachments_for_upload =
674 sync_data_local.GetLocalAttachmentsForUpload();
675 new_attachments->insert(new_attachments->end(),
676 local_attachments_for_upload.begin(),
677 local_attachments_for_upload.end());
678
679 if (merge_result_.get()) { 612 if (merge_result_.get()) {
680 merge_result_->set_num_items_modified(merge_result_->num_items_modified() + 613 merge_result_->set_num_items_modified(merge_result_->num_items_modified() +
681 1); 614 1);
682 } 615 }
683 // TODO(sync): Support updating other parts of the sync node (title, 616 // TODO(sync): Support updating other parts of the sync node (title,
684 // successor, parent, etc.). 617 // successor, parent, etc.).
685 return syncer::SyncError(); 618 return syncer::SyncError();
686 } 619 }
687 620
688 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( 621 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 void GenericChangeProcessor::StartImpl() { 655 void GenericChangeProcessor::StartImpl() {
723 DCHECK(CalledOnValidThread()); 656 DCHECK(CalledOnValidThread());
724 } 657 }
725 658
726 syncer::UserShare* GenericChangeProcessor::share_handle() const { 659 syncer::UserShare* GenericChangeProcessor::share_handle() const {
727 DCHECK(CalledOnValidThread()); 660 DCHECK(CalledOnValidThread());
728 return share_handle_; 661 return share_handle_;
729 } 662 }
730 663
731 } // namespace browser_sync 664 } // namespace browser_sync
OLDNEW
« no previous file with comments | « components/sync_driver/generic_change_processor.h ('k') | components/sync_driver/generic_change_processor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698