OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 #include "chrome/browser/sync/engine/verify_updates_command.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/location.h" | |
10 #include "chrome/browser/sync/engine/syncer.h" | |
11 #include "chrome/browser/sync/engine/syncer_proto_util.h" | |
12 #include "chrome/browser/sync/engine/syncer_types.h" | |
13 #include "chrome/browser/sync/engine/syncer_util.h" | |
14 #include "chrome/browser/sync/engine/syncproto.h" | |
15 #include "chrome/browser/sync/syncable/syncable.h" | |
16 #include "sync/protocol/bookmark_specifics.pb.h" | |
17 | |
18 namespace browser_sync { | |
19 | |
20 using syncable::WriteTransaction; | |
21 | |
22 using syncable::GET_BY_ID; | |
23 using syncable::SYNCER; | |
24 | |
25 VerifyUpdatesCommand::VerifyUpdatesCommand() {} | |
26 VerifyUpdatesCommand::~VerifyUpdatesCommand() {} | |
27 | |
28 std::set<ModelSafeGroup> VerifyUpdatesCommand::GetGroupsToChange( | |
29 const sessions::SyncSession& session) const { | |
30 std::set<ModelSafeGroup> groups_with_updates; | |
31 | |
32 const GetUpdatesResponse& updates = | |
33 session.status_controller().updates_response().get_updates(); | |
34 for (int i = 0; i < updates.entries().size(); i++) { | |
35 groups_with_updates.insert( | |
36 GetGroupForModelType(syncable::GetModelType(updates.entries(i)), | |
37 session.routing_info())); | |
38 } | |
39 | |
40 return groups_with_updates; | |
41 } | |
42 | |
43 SyncerError VerifyUpdatesCommand::ModelChangingExecuteImpl( | |
44 sessions::SyncSession* session) { | |
45 DVLOG(1) << "Beginning Update Verification"; | |
46 syncable::Directory* dir = session->context()->directory(); | |
47 WriteTransaction trans(FROM_HERE, SYNCER, dir); | |
48 sessions::StatusController* status = session->mutable_status_controller(); | |
49 const GetUpdatesResponse& updates = status->updates_response().get_updates(); | |
50 int update_count = updates.entries().size(); | |
51 | |
52 DVLOG(1) << update_count << " entries to verify"; | |
53 for (int i = 0; i < update_count; i++) { | |
54 const SyncEntity& update = | |
55 *reinterpret_cast<const SyncEntity *>(&(updates.entries(i))); | |
56 ModelSafeGroup g = GetGroupForModelType(update.GetModelType(), | |
57 session->routing_info()); | |
58 if (g != status->group_restriction()) | |
59 continue; | |
60 | |
61 VerifyUpdateResult result = VerifyUpdate(&trans, update, | |
62 session->routing_info()); | |
63 status->mutable_update_progress()->AddVerifyResult(result.value, update); | |
64 status->increment_num_updates_downloaded_by(1); | |
65 if (update.deleted()) | |
66 status->increment_num_tombstone_updates_downloaded_by(1); | |
67 } | |
68 | |
69 return SYNCER_OK; | |
70 } | |
71 | |
72 namespace { | |
73 // In the event that IDs match, but tags differ AttemptReuniteClient tag | |
74 // will have refused to unify the update. | |
75 // We should not attempt to apply it at all since it violates consistency | |
76 // rules. | |
77 VerifyResult VerifyTagConsistency(const SyncEntity& entry, | |
78 const syncable::MutableEntry& same_id) { | |
79 if (entry.has_client_defined_unique_tag() && | |
80 entry.client_defined_unique_tag() != | |
81 same_id.Get(syncable::UNIQUE_CLIENT_TAG)) { | |
82 return VERIFY_FAIL; | |
83 } | |
84 return VERIFY_UNDECIDED; | |
85 } | |
86 } // namespace | |
87 | |
88 VerifyUpdatesCommand::VerifyUpdateResult VerifyUpdatesCommand::VerifyUpdate( | |
89 syncable::WriteTransaction* trans, const SyncEntity& entry, | |
90 const ModelSafeRoutingInfo& routes) { | |
91 syncable::Id id = entry.id(); | |
92 VerifyUpdateResult result = {VERIFY_FAIL, GROUP_PASSIVE}; | |
93 | |
94 const bool deleted = entry.has_deleted() && entry.deleted(); | |
95 const bool is_directory = entry.IsFolder(); | |
96 const syncable::ModelType model_type = entry.GetModelType(); | |
97 | |
98 if (!id.ServerKnows()) { | |
99 LOG(ERROR) << "Illegal negative id in received updates"; | |
100 return result; | |
101 } | |
102 { | |
103 const std::string name = SyncerProtoUtil::NameFromSyncEntity(entry); | |
104 if (name.empty() && !deleted) { | |
105 LOG(ERROR) << "Zero length name in non-deleted update"; | |
106 return result; | |
107 } | |
108 } | |
109 | |
110 syncable::MutableEntry same_id(trans, GET_BY_ID, id); | |
111 result.value = SyncerUtil::VerifyNewEntry(entry, &same_id, deleted); | |
112 | |
113 syncable::ModelType placement_type = !deleted ? entry.GetModelType() | |
114 : same_id.good() ? same_id.GetModelType() : syncable::UNSPECIFIED; | |
115 result.placement = GetGroupForModelType(placement_type, routes); | |
116 | |
117 if (VERIFY_UNDECIDED == result.value) { | |
118 result.value = VerifyTagConsistency(entry, same_id); | |
119 } | |
120 | |
121 if (VERIFY_UNDECIDED == result.value) { | |
122 if (deleted) | |
123 result.value = VERIFY_SUCCESS; | |
124 } | |
125 | |
126 // If we have an existing entry, we check here for updates that break | |
127 // consistency rules. | |
128 if (VERIFY_UNDECIDED == result.value) { | |
129 result.value = SyncerUtil::VerifyUpdateConsistency(trans, entry, &same_id, | |
130 deleted, is_directory, model_type); | |
131 } | |
132 | |
133 if (VERIFY_UNDECIDED == result.value) | |
134 result.value = VERIFY_SUCCESS; // No news is good news. | |
135 | |
136 return result; // This might be VERIFY_SUCCESS as well | |
137 } | |
138 | |
139 } // namespace browser_sync | |
OLD | NEW |