| // Copyright 2012 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // Sync protocol for communication between sync client and server. | |
| // If you change or add any fields in this file, update proto_visitors.h and | |
| // potentially proto_enum_conversions.{h, cc}. If you add new Specifics proto, | |
| // also update proto_value_conversions.{h, cc}. | |
| syntax = "proto2"; | |
| option java_multiple_files = true; | |
| option java_package = "org.chromium.components.sync.protocol"; | |
| option optimize_for = LITE_RUNTIME; | |
| package sync_pb; | |
| import "components/sync/protocol/client_commands.proto"; | |
| import "components/sync/protocol/client_debug_info.proto"; | |
| import "components/sync/protocol/data_type_progress_marker.proto"; | |
| import "components/sync/protocol/get_updates_caller_info.proto"; | |
| import "components/sync/protocol/password_sharing_invitation_specifics.proto"; | |
| import "components/sync/protocol/sync_entity.proto"; | |
| import "components/sync/protocol/sync_enums.proto"; | |
| import "components/sync/protocol/sharing_message_specifics.proto"; | |
| // This message contains diagnostic information used to correlate | |
| // commit-related traffic with extensions-related mutations to the | |
| // data models in chromium. It plays no functional role in | |
| // processing this CommitMessage. | |
| message ChromiumExtensionsActivity { | |
| // The human-readable ID identifying the extension responsible | |
| // for the traffic reported in this ChromiumExtensionsActivity. | |
| optional string extension_id = 1; | |
| // How many times the extension successfully invoked a write | |
| // operation through the bookmarks API since the last CommitMessage. | |
| optional uint32 bookmark_writes_since_last_commit = 2; | |
| } | |
| // Client specific configuration information. | |
| message ClientConfigParams { | |
| // The set of data types this client has enabled. Note that this does not | |
| // include proxy types, as they do not have protocol field numbers and are | |
| // placeholder types that implicitly enable protocol types. | |
| repeated int32 enabled_type_ids = 1; | |
| // Whether the PROXY_TABS proxy datatype is enabled on this client. | |
| // Deprecated and not populated anymore since M120. | |
| optional bool tabs_datatype_enabled = 2 [deprecated = true]; | |
| // Whether the account(s) present in the content area's cookie jar match the | |
| // chrome account. If multiple accounts are present in the cookie jar, a | |
| // mismatch implies all of them are different from the chrome account. | |
| optional bool cookie_jar_mismatch = 3; | |
| // Indicates that the client is not aware of any other active clients | |
| // interested in the committed data types. This flag shows that it is not | |
| // necessary to send invalidations for the committed data. A client is | |
| // considered active if it's DeviceInfo has updated recent enough. This flag | |
| // does not take into account whether standalone invalidations are enabled (as | |
| // opposed to `single_client_with_standalone_invalidations`). However, it's | |
| // set depending on interested data types of other devices, e.g. if there are | |
| // other devices but they are not interested in SESSION data type, and current | |
| // commit request contains only SESSION, it will be set to true. | |
| // Introduced in M88. | |
| optional bool single_client = 4; | |
| // A list of FCM registration tokens which are obtained from other clients. | |
| // This list is used by the server to send invalidations to all other clients. | |
| // If the list is empty, the server should treat this as "there is no | |
| // information about other clients". In practice, this happens by the next | |
| // causes: | |
| // 1. This is the old client which doesn't set this field. | |
| // 2. There are too many active devices and the list would have too many | |
| // items. | |
| // 3. An empty list could also mean that the current client is the only | |
| // client. This case should be covered by the | |
| // `single_client_with_standalone_invalidations` field instead (otherwise it | |
| // could be mixed up with older clients). The server doesn't have to use this | |
| // field and can ignore it. Note that this list does not take into account | |
| // interested data types from the other clients. | |
| // Introduced in M89. | |
| repeated string devices_fcm_registration_tokens = 5; | |
| // Similar to `single_client` but takes into account only clients with enabled | |
| // sync standalone invalidations. When set to true, there are no other clients | |
| // with sync standalone invalidations interested in the committing types and | |
| // hence it's not necessary to send out standalone invalidations (it may still | |
| // be necessary to send out invalidations using the legacy system, see | |
| // `single_client` instead). | |
| // Introduced in M105. | |
| optional bool single_client_with_standalone_invalidations = 6; | |
| // Similar to `devices_fcm_registration_tokens` but takes into account clients | |
| // which are subscribed to the data types which are committed in current | |
| // commit request. | |
| // A list of FCM registration tokens which are obtained from other clients. | |
| // This list is used by the server to send invalidations to all other clients. | |
| // If the list is empty, the server should treat this as "there is no | |
| // information about other clients". In practice, this happens by the next | |
| // causes: | |
| // 1. This is the old client which doesn't set this field. | |
| // 2. There are too many active devices and the list would have too many | |
| // items. | |
| // 3. An empty list could also mean that the current client is the only | |
| // client. This case should be covered by the | |
| // `single_client_with_standalone_invalidations` field instead (otherwise it | |
| // could be mixed up with older clients). The server doesn't have to use this | |
| // field and can ignore it. | |
| // Introduced in M105. | |
| repeated string fcm_registration_tokens_for_interested_clients = 7; | |
| // Similar to `single_client` but takes into account only clients which are | |
| // subscribed to old invalidations (i.e. not subscribed to sync standalone | |
| // invalidations). When set to true, there are no other clients subscribed to | |
| // old invalidations. Note that opposed to `single_client`, this flag does not | |
| // always take into account the list of interested data types (because | |
| // interested data types were introduced in M89). When the list is empty, a | |
| // client is considered to be subscribed to all data types. Note that "single | |
| // client" is a bit misleading since this will also be true if there are no | |
| // clients with old invalidations at all. | |
| // Introduced in M110. | |
| optional bool single_client_with_old_invalidations = 8; | |
| } | |
| message CommitMessage { | |
| repeated SyncEntity entries = 1; | |
| // A GUID that identifies the committing sync client. This value will be | |
| // returned as originator_cache_guid for any new items. | |
| optional string cache_guid = 2; | |
| repeated ChromiumExtensionsActivity extensions_activity = 3; | |
| // The configuration of this client at commit time. Used by the server to | |
| // make commit-time decisions about how to process datatypes that might | |
| // involve server-side interaction, and e.g require explicit user intent for | |
| // syncing a particular data type regardless of whether a commit for that | |
| // datatype is currently being sent up. | |
| optional ClientConfigParams config_params = 4; | |
| // Set of optional per-client datatype contexts. | |
| repeated DataTypeContext client_contexts = 5; | |
| // This field need to be 256 bytes if set. This attempts to mitigate CRIME | |
| // attacks when sync communicate from client to server with compression. So if | |
| // compression is used, this need to set a 256 random ASCII bytes. If no | |
| // compression, this field should not be set. The server can ignore the | |
| // padding. | |
| optional string padding = 6; | |
| } | |
| message GetUpdatesMessage { | |
| // Indicates the reason for the GetUpdatesMessage. | |
| // This was *mostly* deprecated in M29. GetUpdatesOrigin is the new way to | |
| // encode the reason for the GetUpdates request, but some parts of the server | |
| // still rely on this field. It also still contains the | |
| // "notifications_enabled" flag which needs to be moved elsewhere before this | |
| // can be fully removed. See https://crbug.com/510165. | |
| optional GetUpdatesCallerInfo caller_info = 2; | |
| // Indicates whether related folders should be fetched. | |
| optional bool fetch_folders = 3 [default = true]; | |
| // Per-datatype progress marker. | |
| // | |
| // With the exception of certain configuration or initial sync requests, the | |
| // client should include one instance of this field for each enabled data | |
| // type. | |
| repeated DataTypeProgressMarker from_progress_marker = 6; | |
| // Indicates whether the response should be sent in chunks. This may be | |
| // needed for devices with limited memory resources. If true, the response | |
| // will include one or more ClientToServerResponses, with the first one | |
| // containing GetUpdatesMetadataResponse, and the remaining ones, if any, | |
| // containing GetUpdatesStreamingResponse. These ClientToServerResponses are | |
| // delimited by a length prefix, which is encoded as a varint. | |
| optional bool streaming = 7 [default = false]; | |
| // Whether the client needs the server to provide an encryption key for this | |
| // account. | |
| // Note: this should typically only be set on the first GetUpdates a client | |
| // requests. Clients are expected to persist the encryption key from then on. | |
| // The allowed frequency for requesting encryption keys is much lower than | |
| // other datatypes, so repeated usage will likely result in throttling. | |
| optional bool need_encryption_key = 8 [default = false]; | |
| // This value is an updated version of the GetUpdatesCallerInfo's | |
| // GetUpdatesSource. It describes the reason for the GetUpdate request. | |
| optional SyncEnums.GetUpdatesOrigin get_updates_origin = 9; | |
| // Whether this GU also serves as a retry GU. Any GU that happens after | |
| // retry timer timeout is a retry GU effectively. | |
| optional bool is_retry = 10 [default = false]; | |
| // Set of optional per-client datatype contexts. | |
| repeated DataTypeContext client_contexts = 11; | |
| reserved 1; | |
| reserved "from_timestamp"; | |
| reserved 4; | |
| reserved "requested_types"; | |
| reserved 5; | |
| reserved "batch_size"; | |
| reserved 1000; | |
| reserved "create_mobile_bookmarks_folder"; | |
| } | |
| // Message from a client asking the server to clear its data. This causes the | |
| // server to generate a new store birthday, which allows dealing reliably with | |
| // in-flight requests (in particular commits) from other clients. | |
| message ClearServerDataMessage { | |
| // No arguments needed as the store birthday and user identifier are part of | |
| // an enclosing message. | |
| } | |
| // Response to a ClearServerData request. | |
| message ClearServerDataResponse { | |
| // No result fields necessary. Success/failure is indicated in | |
| // ClientToServerResponse. | |
| } | |
| // The client must preserve, store, and resend the chip bag with | |
| // every request. The server depends on the chip bag in order | |
| // to precisely choreograph a client-server state machines. | |
| // | |
| // Because the client stores and sends this data on every request, | |
| // the contents of the chip bag should be kept relatively small. | |
| // | |
| // If the server does not return a chip bag, the client must assume | |
| // that there has been no change to the chip bag. The client must | |
| // resend the bag of chips it had prior on the next request. | |
| // | |
| // The client must make the chip bag durable if and only if it | |
| // processes the response from the server. | |
| message ChipBag { | |
| // Server chips are deliberately oqaque, allowing the server | |
| // to encapsulate its state machine logic. | |
| optional bytes server_chips = 1; | |
| } | |
| // Information about the syncer's state. | |
| message ClientStatus { | |
| // Flag to indicate if the client has detected hierarchy conflcits. The flag | |
| // is left unset if update application has not been attempted yet. | |
| // | |
| // The server should attempt to resolve any hierarchy conflicts when this flag | |
| // is set. The client may not assume that any particular action will be | |
| // taken. There is no guarantee the problem will be addressed in a reasonable | |
| // amount of time. | |
| // TODO(crbug.com/40833583): Deprecated in M103. | |
| optional bool hierarchy_conflict_detected = 1 [deprecated = true]; | |
| // Whether the client has full sync (or, sync the feature) enabled or not. | |
| optional bool is_sync_feature_enabled = 2; | |
| } | |
| message ClientToServerMessage { | |
| // `share` field is only used on the server for logging and can sometimes | |
| // contain empty string. It is still useful for logging username when it can't | |
| // be derived from access token in case of auth error. | |
| required string share = 1; | |
| optional int32 protocol_version = 2 [default = 99]; | |
| // LINT.IfChange(SyncClientToServerMessageContents) | |
| enum Contents { | |
| COMMIT = 1; | |
| GET_UPDATES = 2; | |
| DEPRECATED_3 = 3; | |
| DEPRECATED_4 = 4; | |
| CLEAR_SERVER_DATA = 5; | |
| } | |
| // LINT.ThenChange(/tools/metrics/histograms/metadata/sync/enums.xml:SyncClientToServerMessageContents) | |
| // Each ClientToServerMessage contains one request defined by the | |
| // message_contents. Each type has a corresponding message field that will be | |
| // present iff the message is of that type. E.g. a commit message will have a | |
| // message_contents of COMMIT and its commit field will be present. | |
| required Contents message_contents = 3; | |
| optional CommitMessage commit = 4; | |
| optional GetUpdatesMessage get_updates = 5; | |
| reserved 6; | |
| reserved "authenticate"; | |
| // Opaque server-provided ID representing an "epoch" of the server-side data. | |
| // Clients must hand this opaque ID back to the server as part of all requests | |
| // within the same sync session (i.e. for all requests to the server except | |
| // the very first GetUpdates request). See analogous field | |
| // ClientToServerResponse.store_birthday for more details about its lifetime. | |
| optional string store_birthday = 7; | |
| reserved 8; | |
| reserved "sync_problem_detected"; | |
| reserved 9; | |
| // Client side state information for debugging purpose. | |
| // This is only sent on the first getupdates of every sync cycle, | |
| // as an optimization to save bandwidth. | |
| optional DebugInfo debug_info = 10; | |
| // Per-client state for use by the server. Sent with every message sent to the | |
| // server. | |
| optional ChipBag bag_of_chips = 11; | |
| // Google API key. | |
| optional string api_key = 12; | |
| // Client's self-reported state. | |
| // The client should set this on every message sent to the server, though its | |
| // member fields may often be unset. | |
| optional ClientStatus client_status = 13; | |
| // The ID that our invalidation client used to identify itself to the server. | |
| // Sending the ID here allows the server to not send notifications of our own | |
| // changes to our invalidator. | |
| // The field was deprecated in M117 and is no longer populated. | |
| optional string invalidator_client_id = 14 [deprecated = true]; | |
| // Identifies this ClientToServerMessage as a clear server data request. This | |
| // field is present when message_contents is CLEAR_SERVER_DATA. | |
| optional ClearServerDataMessage clear_server_data = 15; | |
| } | |
| message CommitResponse { | |
| // WARNING: Do not add new values to this enum. The response_type field was | |
| // required until (including) M149 and old clients will reject unknown enum | |
| // values. New values can only be added once M149 is fully retired. | |
| enum ResponseType { | |
| SUCCESS = 1; | |
| CONFLICT = 2; // You're out of date; update and check your data | |
| // TODO(ncarter): What's the difference between RETRY and TRANSIENT_ERROR? | |
| RETRY = 3; // Someone has a conflicting, non-expired session open | |
| INVALID_MESSAGE = 4; // What the client sent was invalid, and trying again | |
| // won't help. | |
| OVER_QUOTA = 5; // This operation would put you, or you are, over quota | |
| TRANSIENT_ERROR = 6; // Something went wrong; try again in a bit | |
| } | |
| repeated group EntryResponse = 1 { | |
| // This field was required until (including) M149. The server MUST always | |
| // populate it. | |
| optional ResponseType response_type = 2; | |
| // Sync servers may also return a new ID for an existing item, indicating | |
| // a new entry's been created to hold the data the client's sending up. | |
| optional string id_string = 3; | |
| reserved 4; | |
| reserved "parent_id_string"; | |
| reserved 5; | |
| reserved "position_in_parent"; | |
| // The version of this item -- a monotonically increasing value that is | |
| // maintained by the server. See equivalent field in SyncEntity. | |
| // If the returned version is smaller than the version the client already | |
| // knew, the client will ignore the response, which means the item will | |
| // still be considered to require a commit. | |
| optional int64 version = 6; | |
| reserved 7; | |
| reserved "name"; | |
| reserved 8; | |
| reserved "non_unique_name"; | |
| optional string error_message = 9; | |
| // Last modification time (in milliseconds since Unix epoch). Allows the | |
| // server to override the client-supplied mtime during a commit operation. | |
| // TODO(crbug.com/40751358): Delete this field too. | |
| optional int64 mtime = 10 [deprecated = true]; | |
| message DatatypeSpecificError { | |
| oneof datatype_error { | |
| SharingMessageCommitError sharing_message_error = 1; | |
| OutgoingPasswordSharingInvitationCommitError | |
| outgoing_password_sharing_invitation_error = 2; | |
| } | |
| } | |
| // Datatype specific error (if any). | |
| optional DatatypeSpecificError datatype_specific_error = 11; | |
| } | |
| } | |
| message GetUpdatesResponse { | |
| // New sync entries that the client should apply. | |
| repeated SyncEntity entries = 1; | |
| reserved 2; | |
| reserved "new_timestamp"; | |
| reserved 3; | |
| reserved "newest_timestamp"; | |
| // Approximate count of changes remaining - use this for UI feedback. | |
| // If present and zero, this estimate is firm: the server has no changes | |
| // after the current batch. | |
| optional int64 changes_remaining = 4; | |
| // Opaque, per-datatype timestamp-like tokens. Clients should retain and | |
| // persist the values returned in this field, and present them back to the | |
| // server to indicate the starting point for future update requests. | |
| // | |
| // This will be sent only if the client provided `from_progress_marker` | |
| // in the update request. | |
| // | |
| // The server may provide a new progress marker even if this is the end of | |
| // the batch, or if there were no new updates on the server; and the client | |
| // must save these. If the server does not provide a `new_progress_marker` | |
| // value for a particular datatype, when the request provided a | |
| // `from_progress_marker` value for that datatype, the client should | |
| // interpret this to mean "no change from the previous state" and retain its | |
| // previous progress-marker value for that datatype. | |
| repeated DataTypeProgressMarker new_progress_marker = 5; | |
| // The current encryption keys associated with this account. Will be set if | |
| // the GetUpdatesMessage in the request had need_encryption_key == true or | |
| // the server has updated the set of encryption keys (e.g. due to a key | |
| // rotation). | |
| repeated bytes encryption_keys = 6; | |
| // Set of optional datatype contexts server mutations. | |
| repeated DataTypeContext context_mutations = 7; | |
| } | |
| message ClientToServerResponse { | |
| optional CommitResponse commit = 1; | |
| optional GetUpdatesResponse get_updates = 2; | |
| reserved 3; | |
| reserved "authenticate"; | |
| // Up until protocol_version 24, the default was SUCCESS which made it | |
| // impossible to add new enum values since older clients would parse any | |
| // out-of-range value as SUCCESS. Starting with 25, unless explicitly set, | |
| // the error_code will be UNKNOWN so that clients know when they're | |
| // out-of-date. Note also that when using protocol_version < 25, | |
| // TRANSIENT_ERROR is not supported. Instead, the server sends back a HTTP | |
| // 400 error code. This is deprecated now. | |
| optional SyncEnums.ErrorType error_code = 4 [default = UNKNOWN]; | |
| optional string error_message = 5; | |
| // Opaque server-provided ID representing an "epoch" of the server-side data, | |
| // referred to as "birthday" or "store birthday". This ID remains fixed until | |
| // server-side data gets cleared/reset (e.g. via ClearServerDataMessage), | |
| // which clients experience as NOT_MY_BIRTHDAY error, and involves clearing | |
| // all local sync metadata including the cached store birthday. | |
| // | |
| // This mechanism allows the server to implement clear-data/reset | |
| // functionality that reliably identifies and deletes sync entities uploaded | |
| // before the clear-data/reset event (e.g. via ClearServerDataMessage). | |
| // Furthermore, it allows the server to deal reliably with in-flight changes | |
| // from other clients upon clear-data event, because all writes issued with an | |
| // outdated birthday (which in-flight writes would use) can be detected by the | |
| // server. | |
| optional string store_birthday = 6; | |
| optional ClientCommand client_command = 7; | |
| reserved 8; | |
| reserved "profiling_data"; | |
| reserved 9; | |
| reserved 10; | |
| reserved "stream_metadata"; | |
| reserved 11; | |
| reserved "stream_data"; | |
| // The data types whose storage has been migrated. Present when the value of | |
| // error_code is MIGRATION_DONE. | |
| repeated int32 migrated_data_type_id = 12; | |
| message Error { | |
| optional SyncEnums.ErrorType error_type = 1 [default = UNKNOWN]; | |
| optional string error_description = 2; | |
| reserved 3; | |
| reserved "url"; | |
| optional SyncEnums.Action action = 4 [default = UNKNOWN_ACTION]; | |
| // Currently meaningful if `error_type` is throttled or partial_failure. | |
| // In the throttled case, if this field is absent then the whole client | |
| // (all datatypes) is throttled. | |
| // In the partial_failure case, this field denotes partial failures. The | |
| // client should retry those datatypes with exponential backoff. | |
| repeated int32 error_data_type_ids = 5; | |
| } | |
| optional Error error = 13; | |
| // The new per-client state for this client. If set, should be persisted and | |
| // sent with any subsequent ClientToServerMessages. | |
| optional ChipBag new_bag_of_chips = 14; | |
| // Present if this ClientToServerResponse is in response to a ClearServerData | |
| // request. | |
| optional ClearServerDataResponse clear_server_data = 15; | |
| } | |
| // A message to notify the server of certain sync events. Idempotent. Send these | |
| // to the /event endpoint. Note that this message is handled even when coming | |
| // from the legacy client (i.e. for which the server would reject | |
| // GetUpdates/Commit messages), that means breaking server-side changes need to | |
| // be handled carefully. | |
| message EventRequest { | |
| optional SyncDisabledEvent sync_disabled = 1; | |
| } | |
| message EventResponse {} | |
| // A message indicating that the sync engine has been disabled on a client. | |
| message SyncDisabledEvent { | |
| // The GUID that identifies the sync client. | |
| optional string cache_guid = 1; | |
| // The store birthday that the client was using before disabling sync. | |
| optional string store_birthday = 2; | |
| } |