verify_updates_command.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4// 5 6#include "chrome/browser/sync/engine/verify_updates_command.h" 7 8#include "chrome/browser/sync/engine/syncer.h" 9#include "chrome/browser/sync/engine/syncer_proto_util.h" 10#include "chrome/browser/sync/engine/syncer_types.h" 11#include "chrome/browser/sync/engine/syncer_util.h" 12#include "chrome/browser/sync/engine/syncproto.h" 13#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 14#include "chrome/browser/sync/syncable/directory_manager.h" 15#include "chrome/browser/sync/syncable/syncable.h" 16 17namespace browser_sync { 18 19using syncable::ScopedDirLookup; 20using syncable::SyncName; 21using syncable::WriteTransaction; 22 23using syncable::GET_BY_ID; 24using syncable::SYNCER; 25 26VerifyUpdatesCommand::VerifyUpdatesCommand() {} 27VerifyUpdatesCommand::~VerifyUpdatesCommand() {} 28 29void VerifyUpdatesCommand::ModelChangingExecuteImpl( 30 sessions::SyncSession* session) { 31 VLOG(1) << "Beginning Update Verification"; 32 ScopedDirLookup dir(session->context()->directory_manager(), 33 session->context()->account_name()); 34 if (!dir.good()) { 35 LOG(ERROR) << "Scoped dir lookup failed!"; 36 return; 37 } 38 WriteTransaction trans(dir, SYNCER, __FILE__, __LINE__); 39 sessions::StatusController* status = session->status_controller(); 40 const GetUpdatesResponse& updates = status->updates_response().get_updates(); 41 int update_count = updates.entries().size(); 42 43 VLOG(1) << update_count << " entries to verify"; 44 for (int i = 0; i < update_count; i++) { 45 const SyncEntity& update = 46 *reinterpret_cast<const SyncEntity *>(&(updates.entries(i))); 47 ModelSafeGroup g = GetGroupForModelType(update.GetModelType(), 48 session->routing_info()); 49 if (g != status->group_restriction()) 50 continue; 51 52 VerifyUpdateResult result = VerifyUpdate(&trans, update, 53 session->routing_info()); 54 status->mutable_update_progress()->AddVerifyResult(result.value, update); 55 } 56} 57 58namespace { 59// In the event that IDs match, but tags differ AttemptReuniteClient tag 60// will have refused to unify the update. 61// We should not attempt to apply it at all since it violates consistency 62// rules. 63VerifyResult VerifyTagConsistency(const SyncEntity& entry, 64 const syncable::MutableEntry& same_id) { 65 if (entry.has_client_defined_unique_tag() && 66 entry.client_defined_unique_tag() != 67 same_id.Get(syncable::UNIQUE_CLIENT_TAG)) { 68 return VERIFY_FAIL; 69 } 70 return VERIFY_UNDECIDED; 71} 72} // namespace 73 74VerifyUpdatesCommand::VerifyUpdateResult VerifyUpdatesCommand::VerifyUpdate( 75 syncable::WriteTransaction* trans, const SyncEntity& entry, 76 const ModelSafeRoutingInfo& routes) { 77 syncable::Id id = entry.id(); 78 VerifyUpdateResult result = {VERIFY_FAIL, GROUP_PASSIVE}; 79 80 const bool deleted = entry.has_deleted() && entry.deleted(); 81 const bool is_directory = entry.IsFolder(); 82 const syncable::ModelType model_type = entry.GetModelType(); 83 84 if (!id.ServerKnows()) { 85 LOG(ERROR) << "Illegal negative id in received updates"; 86 return result; 87 } 88 { 89 const std::string name = SyncerProtoUtil::NameFromSyncEntity(entry); 90 if (name.empty() && !deleted) { 91 LOG(ERROR) << "Zero length name in non-deleted update"; 92 return result; 93 } 94 } 95 96 syncable::MutableEntry same_id(trans, GET_BY_ID, id); 97 result.value = SyncerUtil::VerifyNewEntry(entry, &same_id, deleted); 98 99 syncable::ModelType placement_type = !deleted ? entry.GetModelType() 100 : same_id.good() ? same_id.GetModelType() : syncable::UNSPECIFIED; 101 result.placement = GetGroupForModelType(placement_type, routes); 102 103 if (VERIFY_UNDECIDED == result.value) { 104 result.value = VerifyTagConsistency(entry, same_id); 105 } 106 107 if (VERIFY_UNDECIDED == result.value) { 108 if (deleted) 109 result.value = VERIFY_SUCCESS; 110 } 111 112 // If we have an existing entry, we check here for updates that break 113 // consistency rules. 114 if (VERIFY_UNDECIDED == result.value) { 115 result.value = SyncerUtil::VerifyUpdateConsistency(trans, entry, &same_id, 116 deleted, is_directory, model_type); 117 } 118 119 if (VERIFY_UNDECIDED == result.value) 120 result.value = VERIFY_SUCCESS; // No news is good news. 121 122 return result; // This might be VERIFY_SUCCESS as well 123} 124 125} // namespace browser_sync 126