1 // Copyright 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 #ifndef SYNC_ENGINE_SYNCER_PROTO_UTIL_H_ 6 #define SYNC_ENGINE_SYNCER_PROTO_UTIL_H_ 7 8 #include <string> 9 10 #include "base/gtest_prod_util.h" 11 #include "base/time/time.h" 12 #include "sync/base/sync_export.h" 13 #include "sync/internal_api/public/base/model_type.h" 14 #include "sync/internal_api/public/util/syncer_error.h" 15 #include "sync/sessions/sync_session.h" 16 #include "sync/syncable/blob.h" 17 18 namespace sync_pb { 19 class ClientToServerMessage; 20 class ClientToServerResponse; 21 class ClientToServerResponse_Error; 22 class CommitResponse_EntryResponse; 23 class EntitySpecifics; 24 class SyncEntity; 25 } 26 27 namespace syncer { 28 29 class ServerConnectionManager; 30 31 namespace sessions { 32 class SyncProtocolError; 33 class SyncSessionContext; 34 } 35 36 namespace syncable { 37 class Directory; 38 class Entry; 39 } 40 41 // Returns the types to migrate from the data in |response|. 42 SYNC_EXPORT_PRIVATE ModelTypeSet GetTypesToMigrate( 43 const sync_pb::ClientToServerResponse& response); 44 45 // Builds a SyncProtocolError from the data in |error|. 46 SYNC_EXPORT_PRIVATE SyncProtocolError ConvertErrorPBToLocalType( 47 const sync_pb::ClientToServerResponse_Error& error); 48 49 class SYNC_EXPORT_PRIVATE SyncerProtoUtil { 50 public: 51 // Posts the given message and fills the buffer with the returned value. 52 // Returns true on success. Also handles store birthday verification: will 53 // produce a SyncError if the birthday is incorrect. 54 // NOTE: This will add all fields that must be sent on every request, which 55 // includes store birthday, protocol version, client chips, api keys, etc. 56 static SyncerError PostClientToServerMessage( 57 sync_pb::ClientToServerMessage* msg, 58 sync_pb::ClientToServerResponse* response, 59 sessions::SyncSession* session); 60 61 // Compares a syncable Entry to SyncEntity, returns true iff the data is 62 // identical. 63 // 64 // TODO(sync): The places where this function is used are arguable big causes 65 // of the fragility, because there's a tendency to freak out the moment the 66 // local and server values diverge. However, this almost always indicates a 67 // sync bug somewhere earlier in the sync cycle. 68 static bool Compare(const syncable::Entry& local_entry, 69 const sync_pb::SyncEntity& server_entry); 70 71 static bool ShouldMaintainPosition(const sync_pb::SyncEntity& sync_entity); 72 73 // Utility methods for converting between syncable::Blobs and protobuf byte 74 // fields. 75 static void CopyProtoBytesIntoBlob(const std::string& proto_bytes, 76 syncable::Blob* blob); 77 static bool ProtoBytesEqualsBlob(const std::string& proto_bytes, 78 const syncable::Blob& blob); 79 static void CopyBlobIntoProtoBytes(const syncable::Blob& blob, 80 std::string* proto_bytes); 81 82 // Extract the name field from a sync entity. 83 static const std::string& NameFromSyncEntity( 84 const sync_pb::SyncEntity& entry); 85 86 // Extract the name field from a commit entry response. 87 static const std::string& NameFromCommitEntryResponse( 88 const sync_pb::CommitResponse_EntryResponse& entry); 89 90 // Persist the bag of chips if it is present in the response. 91 static void PersistBagOfChips( 92 syncable::Directory* dir, 93 const sync_pb::ClientToServerResponse& response); 94 95 // EntitySpecifics is used as a filter for the GetUpdates message to tell 96 // the server which datatypes to send back. This adds a datatype so that 97 // it's included in the filter. 98 static void AddToEntitySpecificDatatypesFilter(ModelType datatype, 99 sync_pb::EntitySpecifics* filter); 100 101 // Get a debug string representation of the client to server response. 102 static std::string ClientToServerResponseDebugString( 103 const sync_pb::ClientToServerResponse& response); 104 105 // Get update contents as a string. Intended for logging, and intended 106 // to have a smaller footprint than the protobuf's built-in pretty printer. 107 static std::string SyncEntityDebugString(const sync_pb::SyncEntity& entry); 108 109 // Pull the birthday from the dir and put it into the msg. 110 static void AddRequestBirthday(syncable::Directory* dir, 111 sync_pb::ClientToServerMessage* msg); 112 113 // Pull the bag of chips from the dir and put it into the msg. 114 static void AddBagOfChips(syncable::Directory* dir, 115 sync_pb::ClientToServerMessage* msg); 116 117 118 // Set the protocol version field in the outgoing message. 119 static void SetProtocolVersion(sync_pb::ClientToServerMessage* msg); 120 121 private: 122 SyncerProtoUtil() {} 123 124 // Helper functions for PostClientToServerMessage. 125 126 // Verifies the store birthday, alerting/resetting as appropriate if there's a 127 // mismatch. Return false if the syncer should be stuck. 128 static bool VerifyResponseBirthday( 129 const sync_pb::ClientToServerResponse& response, 130 syncable::Directory* dir); 131 132 // Returns true if sync is disabled by admin for a dasher account. 133 static bool IsSyncDisabledByAdmin( 134 const sync_pb::ClientToServerResponse& response); 135 136 // Post the message using the scm, and do some processing on the returned 137 // headers. Decode the server response. 138 static bool PostAndProcessHeaders(ServerConnectionManager* scm, 139 sessions::SyncSession* session, 140 const sync_pb::ClientToServerMessage& msg, 141 sync_pb::ClientToServerResponse* response); 142 143 static base::TimeDelta GetThrottleDelay( 144 const sync_pb::ClientToServerResponse& response); 145 146 friend class SyncerProtoUtilTest; 147 FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, AddRequestBirthday); 148 FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, PostAndProcessHeaders); 149 FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, VerifyDisabledByAdmin); 150 FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, VerifyResponseBirthday); 151 FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, HandleThrottlingNoDatatypes); 152 FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, HandleThrottlingWithDatatypes); 153 154 DISALLOW_COPY_AND_ASSIGN(SyncerProtoUtil); 155 }; 156 157 } // namespace syncer 158 159 #endif // SYNC_ENGINE_SYNCER_PROTO_UTIL_H_ 160