OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/sync/glue/generic_change_processor.h" | 5 #include "chrome/browser/sync/glue/generic_change_processor.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
11 #include "sync/api/sync_change.h" | 11 #include "sync/api/sync_change.h" |
12 #include "sync/api/sync_error.h" | 12 #include "sync/api/sync_error.h" |
13 #include "sync/api/syncable_service.h" | 13 #include "sync/api/syncable_service.h" |
14 #include "sync/internal_api/public/base_node.h" | 14 #include "sync/internal_api/public/base_node.h" |
15 #include "sync/internal_api/public/change_record.h" | 15 #include "sync/internal_api/public/change_record.h" |
16 #include "sync/internal_api/public/read_node.h" | 16 #include "sync/internal_api/public/read_node.h" |
17 #include "sync/internal_api/public/read_transaction.h" | 17 #include "sync/internal_api/public/read_transaction.h" |
18 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" | 18 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" |
19 #include "sync/internal_api/public/write_node.h" | 19 #include "sync/internal_api/public/write_node.h" |
20 #include "sync/internal_api/public/write_transaction.h" | 20 #include "sync/internal_api/public/write_transaction.h" |
21 #include "sync/syncable/entry.h" // TODO(tim): Bug 123674. | 21 #include "sync/syncable/entry.h" // TODO(tim): Bug 123674. |
22 | 22 |
23 using content::BrowserThread; | 23 using content::BrowserThread; |
24 | 24 |
25 namespace browser_sync { | 25 namespace browser_sync { |
26 | 26 |
27 GenericChangeProcessor::GenericChangeProcessor( | 27 GenericChangeProcessor::GenericChangeProcessor( |
28 DataTypeErrorHandler* error_handler, | 28 DataTypeErrorHandler* error_handler, |
29 const base::WeakPtr<SyncableService>& local_service, | 29 const base::WeakPtr<csync::SyncableService>& local_service, |
30 csync::UserShare* user_share) | 30 csync::UserShare* user_share) |
31 : ChangeProcessor(error_handler), | 31 : ChangeProcessor(error_handler), |
32 local_service_(local_service), | 32 local_service_(local_service), |
33 share_handle_(user_share) { | 33 share_handle_(user_share) { |
34 DCHECK(CalledOnValidThread()); | 34 DCHECK(CalledOnValidThread()); |
35 } | 35 } |
36 | 36 |
37 GenericChangeProcessor::~GenericChangeProcessor() { | 37 GenericChangeProcessor::~GenericChangeProcessor() { |
38 DCHECK(CalledOnValidThread()); | 38 DCHECK(CalledOnValidThread()); |
39 } | 39 } |
40 | 40 |
41 void GenericChangeProcessor::ApplyChangesFromSyncModel( | 41 void GenericChangeProcessor::ApplyChangesFromSyncModel( |
42 const csync::BaseTransaction* trans, | 42 const csync::BaseTransaction* trans, |
43 const csync::ImmutableChangeRecordList& changes) { | 43 const csync::ImmutableChangeRecordList& changes) { |
44 DCHECK(CalledOnValidThread()); | 44 DCHECK(CalledOnValidThread()); |
45 DCHECK(running()); | 45 DCHECK(running()); |
46 DCHECK(syncer_changes_.empty()); | 46 DCHECK(syncer_changes_.empty()); |
47 for (csync::ChangeRecordList::const_iterator it = | 47 for (csync::ChangeRecordList::const_iterator it = |
48 changes.Get().begin(); it != changes.Get().end(); ++it) { | 48 changes.Get().begin(); it != changes.Get().end(); ++it) { |
49 if (it->action == csync::ChangeRecord::ACTION_DELETE) { | 49 if (it->action == csync::ChangeRecord::ACTION_DELETE) { |
50 syncer_changes_.push_back( | 50 syncer_changes_.push_back( |
51 SyncChange(SyncChange::ACTION_DELETE, | 51 csync::SyncChange(csync::SyncChange::ACTION_DELETE, |
52 SyncData::CreateRemoteData(it->id, it->specifics))); | 52 csync::SyncData::CreateRemoteData(it->id, it->specifics))); |
53 } else { | 53 } else { |
54 SyncChange::SyncChangeType action = | 54 csync::SyncChange::SyncChangeType action = |
55 (it->action == csync::ChangeRecord::ACTION_ADD) ? | 55 (it->action == csync::ChangeRecord::ACTION_ADD) ? |
56 SyncChange::ACTION_ADD : SyncChange::ACTION_UPDATE; | 56 csync::SyncChange::ACTION_ADD : csync::SyncChange::ACTION_UPDATE; |
57 // Need to load specifics from node. | 57 // Need to load specifics from node. |
58 csync::ReadNode read_node(trans); | 58 csync::ReadNode read_node(trans); |
59 if (read_node.InitByIdLookup(it->id) != csync::BaseNode::INIT_OK) { | 59 if (read_node.InitByIdLookup(it->id) != csync::BaseNode::INIT_OK) { |
60 error_handler()->OnSingleDatatypeUnrecoverableError( | 60 error_handler()->OnSingleDatatypeUnrecoverableError( |
61 FROM_HERE, | 61 FROM_HERE, |
62 "Failed to look up data for received change with id " + | 62 "Failed to look up data for received change with id " + |
63 base::Int64ToString(it->id)); | 63 base::Int64ToString(it->id)); |
64 return; | 64 return; |
65 } | 65 } |
66 syncer_changes_.push_back( | 66 syncer_changes_.push_back( |
67 SyncChange(action, | 67 csync::SyncChange(action, |
68 SyncData::CreateRemoteData( | 68 csync::SyncData::CreateRemoteData( |
69 it->id, read_node.GetEntitySpecifics()))); | 69 it->id, read_node.GetEntitySpecifics()))); |
70 } | 70 } |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 void GenericChangeProcessor::CommitChangesFromSyncModel() { | 74 void GenericChangeProcessor::CommitChangesFromSyncModel() { |
75 DCHECK(CalledOnValidThread()); | 75 DCHECK(CalledOnValidThread()); |
76 if (!running()) | 76 if (!running()) |
77 return; | 77 return; |
78 if (syncer_changes_.empty()) | 78 if (syncer_changes_.empty()) |
79 return; | 79 return; |
80 if (!local_service_) { | 80 if (!local_service_) { |
81 syncable::ModelType type = syncer_changes_[0].sync_data().GetDataType(); | 81 syncable::ModelType type = syncer_changes_[0].sync_data().GetDataType(); |
82 SyncError error(FROM_HERE, "Local service destroyed.", type); | 82 csync::SyncError error(FROM_HERE, "Local service destroyed.", type); |
83 error_handler()->OnSingleDatatypeUnrecoverableError(error.location(), | 83 error_handler()->OnSingleDatatypeUnrecoverableError(error.location(), |
84 error.message()); | 84 error.message()); |
85 return; | 85 return; |
86 } | 86 } |
87 SyncError error = local_service_->ProcessSyncChanges(FROM_HERE, | 87 csync::SyncError error = local_service_->ProcessSyncChanges(FROM_HERE, |
88 syncer_changes_); | 88 syncer_changes_); |
89 syncer_changes_.clear(); | 89 syncer_changes_.clear(); |
90 if (error.IsSet()) { | 90 if (error.IsSet()) { |
91 error_handler()->OnSingleDatatypeUnrecoverableError( | 91 error_handler()->OnSingleDatatypeUnrecoverableError( |
92 error.location(), error.message()); | 92 error.location(), error.message()); |
93 } | 93 } |
94 } | 94 } |
95 | 95 |
96 SyncError GenericChangeProcessor::GetSyncDataForType( | 96 csync::SyncError GenericChangeProcessor::GetSyncDataForType( |
97 syncable::ModelType type, | 97 syncable::ModelType type, |
98 SyncDataList* current_sync_data) { | 98 csync::SyncDataList* current_sync_data) { |
99 DCHECK(CalledOnValidThread()); | 99 DCHECK(CalledOnValidThread()); |
100 std::string type_name = syncable::ModelTypeToString(type); | 100 std::string type_name = syncable::ModelTypeToString(type); |
101 csync::ReadTransaction trans(FROM_HERE, share_handle()); | 101 csync::ReadTransaction trans(FROM_HERE, share_handle()); |
102 csync::ReadNode root(&trans); | 102 csync::ReadNode root(&trans); |
103 if (root.InitByTagLookup(syncable::ModelTypeToRootTag(type)) != | 103 if (root.InitByTagLookup(syncable::ModelTypeToRootTag(type)) != |
104 csync::BaseNode::INIT_OK) { | 104 csync::BaseNode::INIT_OK) { |
105 SyncError error(FROM_HERE, | 105 csync::SyncError error(FROM_HERE, |
106 "Server did not create the top-level " + type_name + | 106 "Server did not create the top-level " + type_name + |
107 " node. We might be running against an out-of-date server.", | 107 " node. We might be running against an out-of-date server.", |
108 type); | 108 type); |
109 return error; | 109 return error; |
110 } | 110 } |
111 | 111 |
112 // TODO(akalin): We'll have to do a tree traversal for bookmarks. | 112 // TODO(akalin): We'll have to do a tree traversal for bookmarks. |
113 DCHECK_NE(type, syncable::BOOKMARKS); | 113 DCHECK_NE(type, syncable::BOOKMARKS); |
114 | 114 |
115 int64 sync_child_id = root.GetFirstChildId(); | 115 int64 sync_child_id = root.GetFirstChildId(); |
116 while (sync_child_id != csync::kInvalidId) { | 116 while (sync_child_id != csync::kInvalidId) { |
117 csync::ReadNode sync_child_node(&trans); | 117 csync::ReadNode sync_child_node(&trans); |
118 if (sync_child_node.InitByIdLookup(sync_child_id) != | 118 if (sync_child_node.InitByIdLookup(sync_child_id) != |
119 csync::BaseNode::INIT_OK) { | 119 csync::BaseNode::INIT_OK) { |
120 SyncError error(FROM_HERE, | 120 csync::SyncError error(FROM_HERE, |
121 "Failed to fetch child node for type " + type_name + ".", | 121 "Failed to fetch child node for type " + type_name + ".", |
122 type); | 122 type); |
123 return error; | 123 return error; |
124 } | 124 } |
125 current_sync_data->push_back(SyncData::CreateRemoteData( | 125 current_sync_data->push_back(csync::SyncData::CreateRemoteData( |
126 sync_child_node.GetId(), sync_child_node.GetEntitySpecifics())); | 126 sync_child_node.GetId(), sync_child_node.GetEntitySpecifics())); |
127 sync_child_id = sync_child_node.GetSuccessorId(); | 127 sync_child_id = sync_child_node.GetSuccessorId(); |
128 } | 128 } |
129 return SyncError(); | 129 return csync::SyncError(); |
130 } | 130 } |
131 | 131 |
132 namespace { | 132 namespace { |
133 | 133 |
134 // TODO(isherman): Investigating http://crbug.com/121592 | 134 // TODO(isherman): Investigating http://crbug.com/121592 |
135 // WARNING: this code is sensitive to compiler optimizations. Be careful | 135 // WARNING: this code is sensitive to compiler optimizations. Be careful |
136 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else | 136 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else |
137 // the compiler attempts to merge it with other calls, losing useful information | 137 // the compiler attempts to merge it with other calls, losing useful information |
138 // in breakpad uploads. | 138 // in breakpad uploads. |
139 SyncError LogLookupFailure(csync::BaseNode::InitByLookupResult lookup_result, | 139 csync::SyncError LogLookupFailure( |
140 const tracked_objects::Location& from_here, | 140 csync::BaseNode::InitByLookupResult lookup_result, |
141 const std::string& error_prefix, | 141 const tracked_objects::Location& from_here, |
142 syncable::ModelType type, | 142 const std::string& error_prefix, |
143 DataTypeErrorHandler* error_handler) { | 143 syncable::ModelType type, |
| 144 DataTypeErrorHandler* error_handler) { |
144 switch (lookup_result) { | 145 switch (lookup_result) { |
145 case csync::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD: { | 146 case csync::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD: { |
146 SyncError error; | 147 csync::SyncError error; |
147 error.Reset(from_here, | 148 error.Reset(from_here, |
148 error_prefix + | 149 error_prefix + |
149 "could not find entry matching the lookup criteria.", | 150 "could not find entry matching the lookup criteria.", |
150 type); | 151 type); |
151 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 152 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
152 error.message()); | 153 error.message()); |
153 LOG(ERROR) << "Delete: Bad entry."; | 154 LOG(ERROR) << "Delete: Bad entry."; |
154 return error; | 155 return error; |
155 } | 156 } |
156 case csync::BaseNode::INIT_FAILED_ENTRY_IS_DEL: { | 157 case csync::BaseNode::INIT_FAILED_ENTRY_IS_DEL: { |
157 SyncError error; | 158 csync::SyncError error; |
158 error.Reset(from_here, error_prefix + "entry is already deleted.", type); | 159 error.Reset(from_here, error_prefix + "entry is already deleted.", type); |
159 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 160 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
160 error.message()); | 161 error.message()); |
161 LOG(ERROR) << "Delete: Deleted entry."; | 162 LOG(ERROR) << "Delete: Deleted entry."; |
162 return error; | 163 return error; |
163 } | 164 } |
164 case csync::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: { | 165 case csync::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: { |
165 SyncError error; | 166 csync::SyncError error; |
166 error.Reset(from_here, error_prefix + "unable to decrypt", type); | 167 error.Reset(from_here, error_prefix + "unable to decrypt", type); |
167 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 168 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
168 error.message()); | 169 error.message()); |
169 LOG(ERROR) << "Delete: Undecryptable entry."; | 170 LOG(ERROR) << "Delete: Undecryptable entry."; |
170 return error; | 171 return error; |
171 } | 172 } |
172 case csync::BaseNode::INIT_FAILED_PRECONDITION: { | 173 case csync::BaseNode::INIT_FAILED_PRECONDITION: { |
173 SyncError error; | 174 csync::SyncError error; |
174 error.Reset(from_here, | 175 error.Reset(from_here, |
175 error_prefix + "a precondition was not met for calling init.", | 176 error_prefix + "a precondition was not met for calling init.", |
176 type); | 177 type); |
177 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 178 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
178 error.message()); | 179 error.message()); |
179 LOG(ERROR) << "Delete: Failed precondition."; | 180 LOG(ERROR) << "Delete: Failed precondition."; |
180 return error; | 181 return error; |
181 } | 182 } |
182 default: { | 183 default: { |
183 SyncError error; | 184 csync::SyncError error; |
184 // Should have listed all the possible error cases above. | 185 // Should have listed all the possible error cases above. |
185 error.Reset(from_here, error_prefix + "unknown error", type); | 186 error.Reset(from_here, error_prefix + "unknown error", type); |
186 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 187 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
187 error.message()); | 188 error.message()); |
188 LOG(ERROR) << "Delete: Unknown error."; | 189 LOG(ERROR) << "Delete: Unknown error."; |
189 return error; | 190 return error; |
190 } | 191 } |
191 } | 192 } |
192 } | 193 } |
193 | 194 |
194 SyncError AttemptDelete(const SyncChange& change, | 195 csync::SyncError AttemptDelete(const csync::SyncChange& change, |
195 syncable::ModelType type, | 196 syncable::ModelType type, |
196 const std::string& type_str, | 197 const std::string& type_str, |
197 csync::WriteNode* node, | 198 csync::WriteNode* node, |
198 DataTypeErrorHandler* error_handler) { | 199 DataTypeErrorHandler* error_handler) { |
199 DCHECK_EQ(change.change_type(), SyncChange::ACTION_DELETE); | 200 DCHECK_EQ(change.change_type(), csync::SyncChange::ACTION_DELETE); |
200 if (change.sync_data().IsLocal()) { | 201 if (change.sync_data().IsLocal()) { |
201 const std::string& tag = change.sync_data().GetTag(); | 202 const std::string& tag = change.sync_data().GetTag(); |
202 if (tag.empty()) { | 203 if (tag.empty()) { |
203 SyncError error( | 204 csync::SyncError error( |
204 FROM_HERE, | 205 FROM_HERE, |
205 "Failed to delete " + type_str + " node. Local data, empty tag.", | 206 "Failed to delete " + type_str + " node. Local data, empty tag.", |
206 type); | 207 type); |
207 error_handler->OnSingleDatatypeUnrecoverableError(error.location(), | 208 error_handler->OnSingleDatatypeUnrecoverableError(error.location(), |
208 error.message()); | 209 error.message()); |
209 NOTREACHED(); | 210 NOTREACHED(); |
210 return error; | 211 return error; |
211 } | 212 } |
212 | 213 |
213 csync::BaseNode::InitByLookupResult result = | 214 csync::BaseNode::InitByLookupResult result = |
214 node->InitByClientTagLookup(change.sync_data().GetDataType(), tag); | 215 node->InitByClientTagLookup(change.sync_data().GetDataType(), tag); |
215 if (result != csync::BaseNode::INIT_OK) { | 216 if (result != csync::BaseNode::INIT_OK) { |
216 return LogLookupFailure( | 217 return LogLookupFailure( |
217 result, FROM_HERE, | 218 result, FROM_HERE, |
218 "Failed to delete " + type_str + " node. Local data, ", | 219 "Failed to delete " + type_str + " node. Local data, ", |
219 type, error_handler); | 220 type, error_handler); |
220 } | 221 } |
221 } else { | 222 } else { |
222 csync::BaseNode::InitByLookupResult result = | 223 csync::BaseNode::InitByLookupResult result = |
223 node->InitByIdLookup(change.sync_data().GetRemoteId()); | 224 node->InitByIdLookup(change.sync_data().GetRemoteId()); |
224 if (result != csync::BaseNode::INIT_OK) { | 225 if (result != csync::BaseNode::INIT_OK) { |
225 return LogLookupFailure( | 226 return LogLookupFailure( |
226 result, FROM_HERE, | 227 result, FROM_HERE, |
227 "Failed to delete " + type_str + " node. Non-local data, ", | 228 "Failed to delete " + type_str + " node. Non-local data, ", |
228 type, error_handler); | 229 type, error_handler); |
229 } | 230 } |
230 } | 231 } |
231 node->Remove(); | 232 node->Remove(); |
232 return SyncError(); | 233 return csync::SyncError(); |
233 } | 234 } |
234 | 235 |
235 } // namespace | 236 } // namespace |
236 | 237 |
237 // WARNING: this code is sensitive to compiler optimizations. Be careful | 238 // WARNING: this code is sensitive to compiler optimizations. Be careful |
238 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else | 239 // modifying any code around an OnSingleDatatypeUnrecoverableError call, else |
239 // the compiler attempts to merge it with other calls, losing useful information | 240 // the compiler attempts to merge it with other calls, losing useful information |
240 // in breakpad uploads. | 241 // in breakpad uploads. |
241 SyncError GenericChangeProcessor::ProcessSyncChanges( | 242 csync::SyncError GenericChangeProcessor::ProcessSyncChanges( |
242 const tracked_objects::Location& from_here, | 243 const tracked_objects::Location& from_here, |
243 const SyncChangeList& list_of_changes) { | 244 const csync::SyncChangeList& list_of_changes) { |
244 DCHECK(CalledOnValidThread()); | 245 DCHECK(CalledOnValidThread()); |
245 csync::WriteTransaction trans(from_here, share_handle()); | 246 csync::WriteTransaction trans(from_here, share_handle()); |
246 | 247 |
247 for (SyncChangeList::const_iterator iter = list_of_changes.begin(); | 248 for (csync::SyncChangeList::const_iterator iter = list_of_changes.begin(); |
248 iter != list_of_changes.end(); | 249 iter != list_of_changes.end(); |
249 ++iter) { | 250 ++iter) { |
250 const SyncChange& change = *iter; | 251 const csync::SyncChange& change = *iter; |
251 DCHECK_NE(change.sync_data().GetDataType(), syncable::UNSPECIFIED); | 252 DCHECK_NE(change.sync_data().GetDataType(), syncable::UNSPECIFIED); |
252 syncable::ModelType type = change.sync_data().GetDataType(); | 253 syncable::ModelType type = change.sync_data().GetDataType(); |
253 std::string type_str = syncable::ModelTypeToString(type); | 254 std::string type_str = syncable::ModelTypeToString(type); |
254 csync::WriteNode sync_node(&trans); | 255 csync::WriteNode sync_node(&trans); |
255 if (change.change_type() == SyncChange::ACTION_DELETE) { | 256 if (change.change_type() == csync::SyncChange::ACTION_DELETE) { |
256 SyncError error = AttemptDelete(change, type, type_str, &sync_node, | 257 csync::SyncError error = AttemptDelete(change, type, type_str, &sync_node, |
257 error_handler()); | 258 error_handler()); |
258 if (error.IsSet()) { | 259 if (error.IsSet()) { |
259 NOTREACHED(); | 260 NOTREACHED(); |
260 return error; | 261 return error; |
261 } | 262 } |
262 } else if (change.change_type() == SyncChange::ACTION_ADD) { | 263 } else if (change.change_type() == csync::SyncChange::ACTION_ADD) { |
263 // TODO(sync): Handle other types of creation (custom parents, folders, | 264 // TODO(sync): Handle other types of creation (custom parents, folders, |
264 // etc.). | 265 // etc.). |
265 csync::ReadNode root_node(&trans); | 266 csync::ReadNode root_node(&trans); |
266 if (root_node.InitByTagLookup( | 267 if (root_node.InitByTagLookup( |
267 syncable::ModelTypeToRootTag(change.sync_data().GetDataType())) != | 268 syncable::ModelTypeToRootTag(change.sync_data().GetDataType())) != |
268 csync::BaseNode::INIT_OK) { | 269 csync::BaseNode::INIT_OK) { |
269 SyncError error(FROM_HERE, | 270 csync::SyncError error(FROM_HERE, |
270 "Failed to look up root node for type " + type_str, | 271 "Failed to look up root node for type " + type_str, |
271 type); | 272 type); |
272 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 273 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
273 error.message()); | 274 error.message()); |
274 NOTREACHED(); | 275 NOTREACHED(); |
275 LOG(ERROR) << "Create: no root node."; | 276 LOG(ERROR) << "Create: no root node."; |
276 return error; | 277 return error; |
277 } | 278 } |
278 csync::WriteNode::InitUniqueByCreationResult result = | 279 csync::WriteNode::InitUniqueByCreationResult result = |
279 sync_node.InitUniqueByCreation(change.sync_data().GetDataType(), | 280 sync_node.InitUniqueByCreation(change.sync_data().GetDataType(), |
280 root_node, | 281 root_node, |
281 change.sync_data().GetTag()); | 282 change.sync_data().GetTag()); |
282 if (result != csync::WriteNode::INIT_SUCCESS) { | 283 if (result != csync::WriteNode::INIT_SUCCESS) { |
283 std::string error_prefix = "Failed to create " + type_str + " node: "; | 284 std::string error_prefix = "Failed to create " + type_str + " node: "; |
284 switch (result) { | 285 switch (result) { |
285 case csync::WriteNode::INIT_FAILED_EMPTY_TAG: { | 286 case csync::WriteNode::INIT_FAILED_EMPTY_TAG: { |
286 SyncError error; | 287 csync::SyncError error; |
287 error.Reset(FROM_HERE, error_prefix + "empty tag", type); | 288 error.Reset(FROM_HERE, error_prefix + "empty tag", type); |
288 error_handler()->OnSingleDatatypeUnrecoverableError( | 289 error_handler()->OnSingleDatatypeUnrecoverableError( |
289 FROM_HERE, error.message()); | 290 FROM_HERE, error.message()); |
290 LOG(ERROR) << "Create: Empty tag."; | 291 LOG(ERROR) << "Create: Empty tag."; |
291 return error; | 292 return error; |
292 } | 293 } |
293 case csync::WriteNode::INIT_FAILED_ENTRY_ALREADY_EXISTS: { | 294 case csync::WriteNode::INIT_FAILED_ENTRY_ALREADY_EXISTS: { |
294 SyncError error; | 295 csync::SyncError error; |
295 error.Reset(FROM_HERE, error_prefix + "entry already exists", type); | 296 error.Reset(FROM_HERE, error_prefix + "entry already exists", type); |
296 error_handler()->OnSingleDatatypeUnrecoverableError( | 297 error_handler()->OnSingleDatatypeUnrecoverableError( |
297 FROM_HERE, error.message()); | 298 FROM_HERE, error.message()); |
298 LOG(ERROR) << "Create: Entry exists."; | 299 LOG(ERROR) << "Create: Entry exists."; |
299 return error; | 300 return error; |
300 } | 301 } |
301 case csync::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: { | 302 case csync::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: { |
302 SyncError error; | 303 csync::SyncError error; |
303 error.Reset(FROM_HERE, error_prefix + "failed to create entry", | 304 error.Reset(FROM_HERE, error_prefix + "failed to create entry", |
304 type); | 305 type); |
305 error_handler()->OnSingleDatatypeUnrecoverableError( | 306 error_handler()->OnSingleDatatypeUnrecoverableError( |
306 FROM_HERE, error.message()); | 307 FROM_HERE, error.message()); |
307 LOG(ERROR) << "Create: Could not create entry."; | 308 LOG(ERROR) << "Create: Could not create entry."; |
308 return error; | 309 return error; |
309 } | 310 } |
310 case csync::WriteNode::INIT_FAILED_SET_PREDECESSOR: { | 311 case csync::WriteNode::INIT_FAILED_SET_PREDECESSOR: { |
311 SyncError error; | 312 csync::SyncError error; |
312 error.Reset(FROM_HERE, error_prefix + "failed to set predecessor", | 313 error.Reset(FROM_HERE, error_prefix + "failed to set predecessor", |
313 type); | 314 type); |
314 error_handler()->OnSingleDatatypeUnrecoverableError( | 315 error_handler()->OnSingleDatatypeUnrecoverableError( |
315 FROM_HERE, error.message()); | 316 FROM_HERE, error.message()); |
316 LOG(ERROR) << "Create: Bad predecessor."; | 317 LOG(ERROR) << "Create: Bad predecessor."; |
317 return error; | 318 return error; |
318 } | 319 } |
319 default: { | 320 default: { |
320 SyncError error; | 321 csync::SyncError error; |
321 error.Reset(FROM_HERE, error_prefix + "unknown error", type); | 322 error.Reset(FROM_HERE, error_prefix + "unknown error", type); |
322 error_handler()->OnSingleDatatypeUnrecoverableError( | 323 error_handler()->OnSingleDatatypeUnrecoverableError( |
323 FROM_HERE, error.message()); | 324 FROM_HERE, error.message()); |
324 LOG(ERROR) << "Create: Unknown error."; | 325 LOG(ERROR) << "Create: Unknown error."; |
325 return error; | 326 return error; |
326 } | 327 } |
327 } | 328 } |
328 } | 329 } |
329 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); | 330 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); |
330 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); | 331 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); |
331 } else if (change.change_type() == SyncChange::ACTION_UPDATE) { | 332 } else if (change.change_type() == csync::SyncChange::ACTION_UPDATE) { |
332 // TODO(zea): consider having this logic for all possible changes? | 333 // TODO(zea): consider having this logic for all possible changes? |
333 csync::BaseNode::InitByLookupResult result = | 334 csync::BaseNode::InitByLookupResult result = |
334 sync_node.InitByClientTagLookup(change.sync_data().GetDataType(), | 335 sync_node.InitByClientTagLookup(change.sync_data().GetDataType(), |
335 change.sync_data().GetTag()); | 336 change.sync_data().GetTag()); |
336 if (result != csync::BaseNode::INIT_OK) { | 337 if (result != csync::BaseNode::INIT_OK) { |
337 if (result == csync::BaseNode::INIT_FAILED_PRECONDITION) { | 338 if (result == csync::BaseNode::INIT_FAILED_PRECONDITION) { |
338 SyncError error; | 339 csync::SyncError error; |
339 error.Reset(FROM_HERE, | 340 error.Reset(FROM_HERE, |
340 "Failed to load entry w/empty tag for " + type_str + ".", | 341 "Failed to load entry w/empty tag for " + type_str + ".", |
341 type); | 342 type); |
342 error_handler()->OnSingleDatatypeUnrecoverableError( | 343 error_handler()->OnSingleDatatypeUnrecoverableError( |
343 FROM_HERE, error.message()); | 344 FROM_HERE, error.message()); |
344 LOG(ERROR) << "Update: Empty tag."; | 345 LOG(ERROR) << "Update: Empty tag."; |
345 return error; | 346 return error; |
346 } else if (result == csync::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) { | 347 } else if (result == csync::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) { |
347 SyncError error; | 348 csync::SyncError error; |
348 error.Reset(FROM_HERE, | 349 error.Reset(FROM_HERE, |
349 "Failed to load bad entry for " + type_str + ".", | 350 "Failed to load bad entry for " + type_str + ".", |
350 type); | 351 type); |
351 error_handler()->OnSingleDatatypeUnrecoverableError( | 352 error_handler()->OnSingleDatatypeUnrecoverableError( |
352 FROM_HERE, error.message()); | 353 FROM_HERE, error.message()); |
353 LOG(ERROR) << "Update: bad entry."; | 354 LOG(ERROR) << "Update: bad entry."; |
354 return error; | 355 return error; |
355 } else if (result == csync::BaseNode::INIT_FAILED_ENTRY_IS_DEL) { | 356 } else if (result == csync::BaseNode::INIT_FAILED_ENTRY_IS_DEL) { |
356 SyncError error; | 357 csync::SyncError error; |
357 error.Reset(FROM_HERE, | 358 error.Reset(FROM_HERE, |
358 "Failed to load deleted entry for " + type_str + ".", | 359 "Failed to load deleted entry for " + type_str + ".", |
359 type); | 360 type); |
360 error_handler()->OnSingleDatatypeUnrecoverableError( | 361 error_handler()->OnSingleDatatypeUnrecoverableError( |
361 FROM_HERE, error.message()); | 362 FROM_HERE, error.message()); |
362 LOG(ERROR) << "Update: deleted entry."; | 363 LOG(ERROR) << "Update: deleted entry."; |
363 return error; | 364 return error; |
364 } else { | 365 } else { |
365 csync::Cryptographer* crypto = trans.GetCryptographer(); | 366 csync::Cryptographer* crypto = trans.GetCryptographer(); |
366 syncable::ModelTypeSet encrypted_types(crypto->GetEncryptedTypes()); | 367 syncable::ModelTypeSet encrypted_types(crypto->GetEncryptedTypes()); |
367 const sync_pb::EntitySpecifics& specifics = | 368 const sync_pb::EntitySpecifics& specifics = |
368 sync_node.GetEntry()->Get(syncable::SPECIFICS); | 369 sync_node.GetEntry()->Get(syncable::SPECIFICS); |
369 CHECK(specifics.has_encrypted()); | 370 CHECK(specifics.has_encrypted()); |
370 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted()); | 371 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted()); |
371 const bool agreement = encrypted_types.Has(type); | 372 const bool agreement = encrypted_types.Has(type); |
372 if (!agreement && !can_decrypt) { | 373 if (!agreement && !can_decrypt) { |
373 SyncError error; | 374 csync::SyncError error; |
374 error.Reset(FROM_HERE, | 375 error.Reset(FROM_HERE, |
375 "Failed to load encrypted entry, missing key and " | 376 "Failed to load encrypted entry, missing key and " |
376 "nigori mismatch for " + type_str + ".", | 377 "nigori mismatch for " + type_str + ".", |
377 type); | 378 type); |
378 error_handler()->OnSingleDatatypeUnrecoverableError( | 379 error_handler()->OnSingleDatatypeUnrecoverableError( |
379 FROM_HERE, error.message()); | 380 FROM_HERE, error.message()); |
380 LOG(ERROR) << "Update: encr case 1."; | 381 LOG(ERROR) << "Update: encr case 1."; |
381 return error; | 382 return error; |
382 } else if (agreement && can_decrypt) { | 383 } else if (agreement && can_decrypt) { |
383 SyncError error; | 384 csync::SyncError error; |
384 error.Reset(FROM_HERE, | 385 error.Reset(FROM_HERE, |
385 "Failed to load encrypted entry, we have the key " | 386 "Failed to load encrypted entry, we have the key " |
386 "and the nigori matches (?!) for " + type_str + ".", | 387 "and the nigori matches (?!) for " + type_str + ".", |
387 type); | 388 type); |
388 error_handler()->OnSingleDatatypeUnrecoverableError( | 389 error_handler()->OnSingleDatatypeUnrecoverableError( |
389 FROM_HERE, error.message()); | 390 FROM_HERE, error.message()); |
390 LOG(ERROR) << "Update: encr case 2."; | 391 LOG(ERROR) << "Update: encr case 2."; |
391 return error; | 392 return error; |
392 } else if (agreement) { | 393 } else if (agreement) { |
393 SyncError error; | 394 csync::SyncError error; |
394 error.Reset(FROM_HERE, | 395 error.Reset(FROM_HERE, |
395 "Failed to load encrypted entry, missing key and " | 396 "Failed to load encrypted entry, missing key and " |
396 "the nigori matches for " + type_str + ".", | 397 "the nigori matches for " + type_str + ".", |
397 type); | 398 type); |
398 error_handler()->OnSingleDatatypeUnrecoverableError( | 399 error_handler()->OnSingleDatatypeUnrecoverableError( |
399 FROM_HERE, error.message()); | 400 FROM_HERE, error.message()); |
400 LOG(ERROR) << "Update: encr case 3."; | 401 LOG(ERROR) << "Update: encr case 3."; |
401 return error; | 402 return error; |
402 } else { | 403 } else { |
403 SyncError error; | 404 csync::SyncError error; |
404 error.Reset(FROM_HERE, | 405 error.Reset(FROM_HERE, |
405 "Failed to load encrypted entry, we have the key" | 406 "Failed to load encrypted entry, we have the key" |
406 "(?!) and nigori mismatch for " + type_str + ".", | 407 "(?!) and nigori mismatch for " + type_str + ".", |
407 type); | 408 type); |
408 error_handler()->OnSingleDatatypeUnrecoverableError( | 409 error_handler()->OnSingleDatatypeUnrecoverableError( |
409 FROM_HERE, error.message()); | 410 FROM_HERE, error.message()); |
410 LOG(ERROR) << "Update: encr case 4."; | 411 LOG(ERROR) << "Update: encr case 4."; |
411 return error; | 412 return error; |
412 } | 413 } |
413 } | 414 } |
414 } else { | 415 } else { |
415 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); | 416 sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle())); |
416 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); | 417 sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics()); |
417 // TODO(sync): Support updating other parts of the sync node (title, | 418 // TODO(sync): Support updating other parts of the sync node (title, |
418 // successor, parent, etc.). | 419 // successor, parent, etc.). |
419 } | 420 } |
420 } else { | 421 } else { |
421 SyncError error(FROM_HERE, | 422 csync::SyncError error( |
422 "Received unset SyncChange in the change processor.", | 423 FROM_HERE, |
423 type); | 424 "Received unset csync::SyncChange in the change processor.", |
| 425 type); |
424 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, | 426 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, |
425 error.message()); | 427 error.message()); |
426 NOTREACHED(); | 428 NOTREACHED(); |
427 LOG(ERROR) << "Unset sync change."; | 429 LOG(ERROR) << "Unset sync change."; |
428 return error; | 430 return error; |
429 } | 431 } |
430 } | 432 } |
431 return SyncError(); | 433 return csync::SyncError(); |
432 } | 434 } |
433 | 435 |
434 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( | 436 bool GenericChangeProcessor::SyncModelHasUserCreatedNodes( |
435 syncable::ModelType type, | 437 syncable::ModelType type, |
436 bool* has_nodes) { | 438 bool* has_nodes) { |
437 DCHECK(CalledOnValidThread()); | 439 DCHECK(CalledOnValidThread()); |
438 DCHECK(has_nodes); | 440 DCHECK(has_nodes); |
439 DCHECK_NE(type, syncable::UNSPECIFIED); | 441 DCHECK_NE(type, syncable::UNSPECIFIED); |
440 std::string type_name = syncable::ModelTypeToString(type); | 442 std::string type_name = syncable::ModelTypeToString(type); |
441 std::string err_str = "Server did not create the top-level " + type_name + | 443 std::string err_str = "Server did not create the top-level " + type_name + |
(...skipping 30 matching lines...) Expand all Loading... |
472 void GenericChangeProcessor::StopImpl() { | 474 void GenericChangeProcessor::StopImpl() { |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
474 } | 476 } |
475 | 477 |
476 csync::UserShare* GenericChangeProcessor::share_handle() const { | 478 csync::UserShare* GenericChangeProcessor::share_handle() const { |
477 DCHECK(CalledOnValidThread()); | 479 DCHECK(CalledOnValidThread()); |
478 return share_handle_; | 480 return share_handle_; |
479 } | 481 } |
480 | 482 |
481 } // namespace browser_sync | 483 } // namespace browser_sync |
OLD | NEW |