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 "sync/engine/syncer_proto_util.h" | 5 #include "sync/engine/syncer_proto_util.h" |
6 | 6 |
7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 #include "google_apis/google_api_keys.h" | 9 #include "google_apis/google_api_keys.h" |
10 #include "sync/engine/net/server_connection_manager.h" | 10 #include "sync/engine/net/server_connection_manager.h" |
11 #include "sync/engine/syncer.h" | 11 #include "sync/engine/syncer.h" |
12 #include "sync/engine/syncer_types.h" | 12 #include "sync/engine/syncer_types.h" |
13 #include "sync/engine/throttled_data_type_tracker.h" | 13 #include "sync/engine/throttled_data_type_tracker.h" |
14 #include "sync/engine/traffic_logger.h" | 14 #include "sync/engine/traffic_logger.h" |
15 #include "sync/internal_api/public/base/model_type.h" | 15 #include "sync/internal_api/public/base/model_type.h" |
16 #include "sync/protocol/sync.pb.h" | |
17 #include "sync/protocol/sync_enums.pb.h" | 16 #include "sync/protocol/sync_enums.pb.h" |
18 #include "sync/protocol/sync_protocol_error.h" | 17 #include "sync/protocol/sync_protocol_error.h" |
19 #include "sync/sessions/sync_session.h" | 18 #include "sync/sessions/sync_session.h" |
20 #include "sync/syncable/directory.h" | 19 #include "sync/syncable/directory.h" |
21 #include "sync/syncable/entry.h" | 20 #include "sync/syncable/entry.h" |
22 #include "sync/syncable/syncable-inl.h" | 21 #include "sync/syncable/syncable-inl.h" |
23 #include "sync/syncable/syncable_proto_util.h" | 22 #include "sync/syncable/syncable_proto_util.h" |
24 #include "sync/util/time.h" | 23 #include "sync/util/time.h" |
25 | 24 |
26 using std::string; | 25 using std::string; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 case HttpResponse::RETRY: | 99 case HttpResponse::RETRY: |
101 return SERVER_RETURN_TRANSIENT_ERROR; | 100 return SERVER_RETURN_TRANSIENT_ERROR; |
102 case HttpResponse::SERVER_CONNECTION_OK: | 101 case HttpResponse::SERVER_CONNECTION_OK: |
103 case HttpResponse::NONE: | 102 case HttpResponse::NONE: |
104 default: | 103 default: |
105 NOTREACHED(); | 104 NOTREACHED(); |
106 return UNSET; | 105 return UNSET; |
107 } | 106 } |
108 } | 107 } |
109 | 108 |
| 109 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType( |
| 110 const sync_pb::SyncEnums::ErrorType& error_type) { |
| 111 switch (error_type) { |
| 112 case sync_pb::SyncEnums::SUCCESS: |
| 113 return SYNC_SUCCESS; |
| 114 case sync_pb::SyncEnums::NOT_MY_BIRTHDAY: |
| 115 return NOT_MY_BIRTHDAY; |
| 116 case sync_pb::SyncEnums::THROTTLED: |
| 117 return THROTTLED; |
| 118 case sync_pb::SyncEnums::CLEAR_PENDING: |
| 119 return CLEAR_PENDING; |
| 120 case sync_pb::SyncEnums::TRANSIENT_ERROR: |
| 121 return TRANSIENT_ERROR; |
| 122 case sync_pb::SyncEnums::MIGRATION_DONE: |
| 123 return MIGRATION_DONE; |
| 124 case sync_pb::SyncEnums::UNKNOWN: |
| 125 return UNKNOWN_ERROR; |
| 126 case sync_pb::SyncEnums::USER_NOT_ACTIVATED: |
| 127 case sync_pb::SyncEnums::AUTH_INVALID: |
| 128 case sync_pb::SyncEnums::ACCESS_DENIED: |
| 129 return INVALID_CREDENTIAL; |
| 130 default: |
| 131 NOTREACHED(); |
| 132 return UNKNOWN_ERROR; |
| 133 } |
| 134 } |
| 135 |
| 136 ClientAction ConvertClientActionPBToLocalClientAction( |
| 137 const sync_pb::SyncEnums::Action& action) { |
| 138 switch (action) { |
| 139 case sync_pb::SyncEnums::UPGRADE_CLIENT: |
| 140 return UPGRADE_CLIENT; |
| 141 case sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC: |
| 142 return CLEAR_USER_DATA_AND_RESYNC; |
| 143 case sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT: |
| 144 return ENABLE_SYNC_ON_ACCOUNT; |
| 145 case sync_pb::SyncEnums::STOP_AND_RESTART_SYNC: |
| 146 return STOP_AND_RESTART_SYNC; |
| 147 case sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT: |
| 148 return DISABLE_SYNC_ON_CLIENT; |
| 149 case sync_pb::SyncEnums::UNKNOWN_ACTION: |
| 150 return UNKNOWN_ACTION; |
| 151 default: |
| 152 NOTREACHED(); |
| 153 return UNKNOWN_ACTION; |
| 154 } |
| 155 } |
| 156 |
110 } // namespace | 157 } // namespace |
111 | 158 |
112 // static | 159 ModelTypeSet GetTypesToMigrate(const ClientToServerResponse& response) { |
113 void SyncerProtoUtil::HandleMigrationDoneResponse( | |
114 const ClientToServerResponse* response, | |
115 sessions::SyncSession* session) { | |
116 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size()) | |
117 << "MIGRATION_DONE but no types specified."; | |
118 ModelTypeSet to_migrate; | 160 ModelTypeSet to_migrate; |
119 for (int i = 0; i < response->migrated_data_type_id_size(); i++) { | 161 for (int i = 0; i < response.migrated_data_type_id_size(); i++) { |
120 int field_number = response->migrated_data_type_id(i); | 162 int field_number = response.migrated_data_type_id(i); |
121 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number); | 163 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number); |
122 if (!IsRealDataType(model_type)) { | 164 if (!IsRealDataType(model_type)) { |
123 NOTREACHED() << "Unknown field number " << field_number; | 165 DLOG(WARNING) << "Unknown field number " << field_number; |
124 continue; | 166 continue; |
125 } | 167 } |
126 to_migrate.Put(model_type); | 168 to_migrate.Put(model_type); |
127 } | 169 } |
128 // TODO(akalin): This should be a set union. | 170 return to_migrate; |
129 session->mutable_status_controller()-> | |
130 set_types_needing_local_migration(to_migrate); | |
131 } | 171 } |
132 | 172 |
133 // static | 173 SyncProtocolError ConvertErrorPBToLocalType( |
134 bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir, | 174 const sync_pb::ClientToServerResponse_Error& error) { |
135 const ClientToServerResponse* response) { | 175 SyncProtocolError sync_protocol_error; |
| 176 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType( |
| 177 error.error_type()); |
| 178 sync_protocol_error.error_description = error.error_description(); |
| 179 sync_protocol_error.url = error.url(); |
| 180 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction( |
| 181 error.action()); |
| 182 |
| 183 if (error.error_data_type_ids_size() > 0) { |
| 184 // THROTTLED is currently the only error code that uses |error_data_types|. |
| 185 DCHECK_EQ(error.error_type(), sync_pb::SyncEnums::THROTTLED); |
| 186 for (int i = 0; i < error.error_data_type_ids_size(); ++i) { |
| 187 int field_number = error.error_data_type_ids(i); |
| 188 ModelType model_type = |
| 189 GetModelTypeFromSpecificsFieldNumber(field_number); |
| 190 if (!IsRealDataType(model_type)) { |
| 191 DLOG(WARNING) << "Unknown field number " << field_number; |
| 192 continue; |
| 193 } |
| 194 sync_protocol_error.error_data_types.Put(model_type); |
| 195 } |
| 196 } |
| 197 |
| 198 return sync_protocol_error; |
| 199 } |
| 200 |
| 201 bool SyncerProtoUtil::VerifyResponseBirthday( |
| 202 const ClientToServerResponse& response, |
| 203 syncable::Directory* dir) { |
136 | 204 |
137 std::string local_birthday = dir->store_birthday(); | 205 std::string local_birthday = dir->store_birthday(); |
138 | 206 |
139 if (local_birthday.empty()) { | 207 if (local_birthday.empty()) { |
140 if (!response->has_store_birthday()) { | 208 if (!response.has_store_birthday()) { |
141 LOG(WARNING) << "Expected a birthday on first sync."; | 209 LOG(WARNING) << "Expected a birthday on first sync."; |
142 return false; | 210 return false; |
143 } | 211 } |
144 | 212 |
145 DVLOG(1) << "New store birthday: " << response->store_birthday(); | 213 DVLOG(1) << "New store birthday: " << response.store_birthday(); |
146 dir->set_store_birthday(response->store_birthday()); | 214 dir->set_store_birthday(response.store_birthday()); |
147 return true; | 215 return true; |
148 } | 216 } |
149 | 217 |
150 // Error situation, but we're not stuck. | 218 // Error situation, but we're not stuck. |
151 if (!response->has_store_birthday()) { | 219 if (!response.has_store_birthday()) { |
152 LOG(WARNING) << "No birthday in server response?"; | 220 LOG(WARNING) << "No birthday in server response?"; |
153 return true; | 221 return true; |
154 } | 222 } |
155 | 223 |
156 if (response->store_birthday() != local_birthday) { | 224 if (response.store_birthday() != local_birthday) { |
157 LOG(WARNING) << "Birthday changed, showing syncer stuck"; | 225 LOG(WARNING) << "Birthday changed, showing syncer stuck"; |
158 return false; | 226 return false; |
159 } | 227 } |
160 | 228 |
161 return true; | 229 return true; |
162 } | 230 } |
163 | 231 |
164 // static | 232 // static |
165 void SyncerProtoUtil::AddRequestBirthday(syncable::Directory* dir, | 233 void SyncerProtoUtil::AddRequestBirthday(syncable::Directory* dir, |
166 ClientToServerMessage* msg) { | 234 ClientToServerMessage* msg) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 if (!message.has_get_updates()) | 326 if (!message.has_get_updates()) |
259 return false; | 327 return false; |
260 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); | 328 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); |
261 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { | 329 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { |
262 if (!message.get_updates().from_progress_marker(i).token().empty()) | 330 if (!message.get_updates().from_progress_marker(i).token().empty()) |
263 return false; | 331 return false; |
264 } | 332 } |
265 return true; | 333 return true; |
266 } | 334 } |
267 | 335 |
268 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType( | |
269 const sync_pb::SyncEnums::ErrorType& error_type) { | |
270 switch (error_type) { | |
271 case sync_pb::SyncEnums::SUCCESS: | |
272 return SYNC_SUCCESS; | |
273 case sync_pb::SyncEnums::NOT_MY_BIRTHDAY: | |
274 return NOT_MY_BIRTHDAY; | |
275 case sync_pb::SyncEnums::THROTTLED: | |
276 return THROTTLED; | |
277 case sync_pb::SyncEnums::CLEAR_PENDING: | |
278 return CLEAR_PENDING; | |
279 case sync_pb::SyncEnums::TRANSIENT_ERROR: | |
280 return TRANSIENT_ERROR; | |
281 case sync_pb::SyncEnums::MIGRATION_DONE: | |
282 return MIGRATION_DONE; | |
283 case sync_pb::SyncEnums::UNKNOWN: | |
284 return UNKNOWN_ERROR; | |
285 case sync_pb::SyncEnums::USER_NOT_ACTIVATED: | |
286 case sync_pb::SyncEnums::AUTH_INVALID: | |
287 case sync_pb::SyncEnums::ACCESS_DENIED: | |
288 return INVALID_CREDENTIAL; | |
289 default: | |
290 NOTREACHED(); | |
291 return UNKNOWN_ERROR; | |
292 } | |
293 } | |
294 | |
295 ClientAction ConvertClientActionPBToLocalClientAction( | |
296 const sync_pb::SyncEnums::Action& action) { | |
297 switch (action) { | |
298 case sync_pb::SyncEnums::UPGRADE_CLIENT: | |
299 return UPGRADE_CLIENT; | |
300 case sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC: | |
301 return CLEAR_USER_DATA_AND_RESYNC; | |
302 case sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT: | |
303 return ENABLE_SYNC_ON_ACCOUNT; | |
304 case sync_pb::SyncEnums::STOP_AND_RESTART_SYNC: | |
305 return STOP_AND_RESTART_SYNC; | |
306 case sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT: | |
307 return DISABLE_SYNC_ON_CLIENT; | |
308 case sync_pb::SyncEnums::UNKNOWN_ACTION: | |
309 return UNKNOWN_ACTION; | |
310 default: | |
311 NOTREACHED(); | |
312 return UNKNOWN_ACTION; | |
313 } | |
314 } | |
315 | |
316 SyncProtocolError ConvertErrorPBToLocalType( | |
317 const ClientToServerResponse::Error& error) { | |
318 SyncProtocolError sync_protocol_error; | |
319 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType( | |
320 error.error_type()); | |
321 sync_protocol_error.error_description = error.error_description(); | |
322 sync_protocol_error.url = error.url(); | |
323 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction( | |
324 error.action()); | |
325 | |
326 if (error.error_data_type_ids_size() > 0) { | |
327 // THROTTLED is currently the only error code that uses |error_data_types|. | |
328 DCHECK_EQ(error.error_type(), sync_pb::SyncEnums::THROTTLED); | |
329 for (int i = 0; i < error.error_data_type_ids_size(); ++i) { | |
330 int field_number = error.error_data_type_ids(i); | |
331 ModelType model_type = | |
332 GetModelTypeFromSpecificsFieldNumber(field_number); | |
333 if (!IsRealDataType(model_type)) { | |
334 NOTREACHED() << "Unknown field number " << field_number; | |
335 continue; | |
336 } | |
337 sync_protocol_error.error_data_types.Put(model_type); | |
338 } | |
339 } | |
340 | |
341 return sync_protocol_error; | |
342 } | |
343 | |
344 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. | 336 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. |
345 SyncProtocolError ConvertLegacyErrorCodeToNewError( | 337 SyncProtocolError ConvertLegacyErrorCodeToNewError( |
346 const sync_pb::SyncEnums::ErrorType& error_type) { | 338 const sync_pb::SyncEnums::ErrorType& error_type) { |
347 SyncProtocolError error; | 339 SyncProtocolError error; |
348 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); | 340 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); |
349 if (error_type == sync_pb::SyncEnums::CLEAR_PENDING || | 341 if (error_type == sync_pb::SyncEnums::CLEAR_PENDING || |
350 error_type == sync_pb::SyncEnums::NOT_MY_BIRTHDAY) { | 342 error_type == sync_pb::SyncEnums::NOT_MY_BIRTHDAY) { |
351 error.action = DISABLE_SYNC_ON_CLIENT; | 343 error.action = DISABLE_SYNC_ON_CLIENT; |
352 } // There is no other action we can compute for legacy server. | 344 } // There is no other action we can compute for legacy server. |
353 return error; | 345 return error; |
354 } | 346 } |
355 | 347 |
356 } // namespace | 348 } // namespace |
357 | 349 |
358 // static | 350 // static |
359 SyncerError SyncerProtoUtil::PostClientToServerMessage( | 351 SyncerError SyncerProtoUtil::PostClientToServerMessage( |
360 ClientToServerMessage* msg, | 352 ClientToServerMessage* msg, |
361 ClientToServerResponse* response, | 353 ClientToServerResponse* response, |
362 SyncSession* session) { | 354 SyncSession* session) { |
363 | |
364 CHECK(response); | 355 CHECK(response); |
365 DCHECK(!msg->get_updates().has_from_timestamp()); // Deprecated. | 356 DCHECK(!msg->get_updates().has_from_timestamp()); // Deprecated. |
366 DCHECK(!msg->get_updates().has_requested_types()); // Deprecated. | 357 DCHECK(!msg->get_updates().has_requested_types()); // Deprecated. |
367 | 358 |
368 // Add must-have fields. | 359 // Add must-have fields. |
369 SetProtocolVersion(msg); | 360 SetProtocolVersion(msg); |
370 AddRequestBirthday(session->context()->directory(), msg); | 361 AddRequestBirthday(session->context()->directory(), msg); |
371 DCHECK(msg->has_store_birthday() || IsVeryFirstGetUpdates(*msg)); | 362 DCHECK(msg->has_store_birthday() || IsVeryFirstGetUpdates(*msg)); |
372 AddBagOfChips(session->context()->directory(), msg); | 363 AddBagOfChips(session->context()->directory(), msg); |
373 msg->set_api_key(google_apis::GetAPIKey()); | 364 msg->set_api_key(google_apis::GetAPIKey()); |
(...skipping 19 matching lines...) Expand all Loading... |
393 LogClientToServerResponse(*response); | 384 LogClientToServerResponse(*response); |
394 session->context()->traffic_recorder()->RecordClientToServerResponse( | 385 session->context()->traffic_recorder()->RecordClientToServerResponse( |
395 *response); | 386 *response); |
396 | 387 |
397 // Persist a bag of chips if it has been sent by the server. | 388 // Persist a bag of chips if it has been sent by the server. |
398 PersistBagOfChips(dir, *response); | 389 PersistBagOfChips(dir, *response); |
399 | 390 |
400 SyncProtocolError sync_protocol_error; | 391 SyncProtocolError sync_protocol_error; |
401 | 392 |
402 // Birthday mismatch overrides any error that is sent by the server. | 393 // Birthday mismatch overrides any error that is sent by the server. |
403 if (!VerifyResponseBirthday(dir, response)) { | 394 if (!VerifyResponseBirthday(*response, dir)) { |
404 sync_protocol_error.error_type = NOT_MY_BIRTHDAY; | 395 sync_protocol_error.error_type = NOT_MY_BIRTHDAY; |
405 sync_protocol_error.action = | 396 sync_protocol_error.action = |
406 DISABLE_SYNC_ON_CLIENT; | 397 DISABLE_SYNC_ON_CLIENT; |
407 } else if (response->has_error()) { | 398 } else if (response->has_error()) { |
408 // This is a new server. Just get the error from the protocol. | 399 // This is a new server. Just get the error from the protocol. |
409 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); | 400 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); |
410 } else { | 401 } else { |
411 // Legacy server implementation. Compute the error based on |error_code|. | 402 // Legacy server implementation. Compute the error based on |error_code|. |
412 sync_protocol_error = ConvertLegacyErrorCodeToNewError( | 403 sync_protocol_error = ConvertLegacyErrorCodeToNewError( |
413 response->error_code()); | 404 response->error_code()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 case THROTTLED: | 449 case THROTTLED: |
459 LOG(WARNING) << "Client silenced by server."; | 450 LOG(WARNING) << "Client silenced by server."; |
460 HandleThrottleError(sync_protocol_error, | 451 HandleThrottleError(sync_protocol_error, |
461 base::TimeTicks::Now() + GetThrottleDelay(*response), | 452 base::TimeTicks::Now() + GetThrottleDelay(*response), |
462 session->context()->throttled_data_type_tracker(), | 453 session->context()->throttled_data_type_tracker(), |
463 session->delegate()); | 454 session->delegate()); |
464 return SERVER_RETURN_THROTTLED; | 455 return SERVER_RETURN_THROTTLED; |
465 case TRANSIENT_ERROR: | 456 case TRANSIENT_ERROR: |
466 return SERVER_RETURN_TRANSIENT_ERROR; | 457 return SERVER_RETURN_TRANSIENT_ERROR; |
467 case MIGRATION_DONE: | 458 case MIGRATION_DONE: |
468 HandleMigrationDoneResponse(response, session); | 459 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size()) |
| 460 << "MIGRATION_DONE but no types specified."; |
| 461 // TODO(akalin): This should be a set union. |
| 462 session->mutable_status_controller()-> |
| 463 set_types_needing_local_migration(GetTypesToMigrate(*response)); |
469 return SERVER_RETURN_MIGRATION_DONE; | 464 return SERVER_RETURN_MIGRATION_DONE; |
470 case CLEAR_PENDING: | 465 case CLEAR_PENDING: |
471 return SERVER_RETURN_CLEAR_PENDING; | 466 return SERVER_RETURN_CLEAR_PENDING; |
472 case NOT_MY_BIRTHDAY: | 467 case NOT_MY_BIRTHDAY: |
473 return SERVER_RETURN_NOT_MY_BIRTHDAY; | 468 return SERVER_RETURN_NOT_MY_BIRTHDAY; |
474 default: | 469 default: |
475 NOTREACHED(); | 470 NOTREACHED(); |
476 return UNSET; | 471 return UNSET; |
477 } | 472 } |
478 } | 473 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 std::string SyncerProtoUtil::ClientToServerResponseDebugString( | 603 std::string SyncerProtoUtil::ClientToServerResponseDebugString( |
609 const ClientToServerResponse& response) { | 604 const ClientToServerResponse& response) { |
610 // Add more handlers as needed. | 605 // Add more handlers as needed. |
611 std::string output; | 606 std::string output; |
612 if (response.has_get_updates()) | 607 if (response.has_get_updates()) |
613 output.append(GetUpdatesResponseString(response.get_updates())); | 608 output.append(GetUpdatesResponseString(response.get_updates())); |
614 return output; | 609 return output; |
615 } | 610 } |
616 | 611 |
617 } // namespace syncer | 612 } // namespace syncer |
OLD | NEW |