1 // Copyright 2015 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 COMPONENTS_SYNC_MODEL_MODEL_TYPE_SYNC_BRIDGE_H_ 6 #define COMPONENTS_SYNC_MODEL_MODEL_TYPE_SYNC_BRIDGE_H_ 7 8 #include <memory> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/optional.h" 14 #include "components/sync/engine/commit_and_get_updates_types.h" 15 #include "components/sync/model/entity_change.h" 16 #include "components/sync/model/model_type_change_processor.h" 17 18 namespace syncer { 19 20 enum class ConflictResolution; 21 class DataBatch; 22 struct DataTypeActivationRequest; 23 struct EntityData; 24 class MetadataChangeList; 25 class ModelError; 26 27 // Interface implemented by model types to receive updates from sync via a 28 // ModelTypeChangeProcessor. Provides a way for sync to update the data and 29 // metadata for entities, as well as the model type state. Sync bridge 30 // implementations must provide their change_processor() with metadata through 31 // ModelReadyToSync() as soon as possible. Once this is called, sync will 32 // immediately begin locally tracking changes and can start syncing with the 33 // server soon afterward. If an error occurs during startup, the processor's 34 // ReportError() method should be called instead of ModelReadyToSync(). 35 class ModelTypeSyncBridge { 36 public: 37 using DataCallback = base::OnceCallback<void(std::unique_ptr<DataBatch>)>; 38 using StorageKeyList = std::vector<std::string>; 39 40 ModelTypeSyncBridge( 41 std::unique_ptr<ModelTypeChangeProcessor> change_processor); 42 43 virtual ~ModelTypeSyncBridge(); 44 45 // Called by the processor as a notification that sync has been started by the 46 // ModelTypeController. 47 virtual void OnSyncStarting(const DataTypeActivationRequest& request); 48 49 // Creates an object used to communicate changes in the sync metadata to the 50 // model type store. 51 virtual std::unique_ptr<MetadataChangeList> CreateMetadataChangeList() = 0; 52 53 // Perform the initial merge between local and sync data. 54 // 55 // If the bridge supports incremental updates, this is only called when a data 56 // type is first enabled to start syncing, and there is no sync metadata. 57 // In this case, best effort should be made to match local and sync data. 58 // 59 // For datatypes that do not support incremental updates, the processor will 60 // call this method every time it gets new sync data from the server. It is 61 // then the responsibility of the bridge to clear all existing sync data, and 62 // replace it with the passed in |entity_data|. 63 // 64 // Storage key in entity_data elements will be set to result of 65 // GetStorageKey() call if the bridge supports it. Otherwise it will be left 66 // empty, bridge is responsible for updating storage keys of new entities with 67 // change_processor()->UpdateStorageKey() in this case. 68 // 69 // If a local and sync data should match/merge but disagree on storage key, 70 // the bridge should delete one of the records (preferably local). Any local 71 // pieces of data that are not present in sync should immediately be Put(...) 72 // to the processor before returning. The same MetadataChangeList that was 73 // passed into this function can be passed to Put(...) calls. Delete(...) can 74 // also be called but should not be needed for most model types. Durable 75 // storage writes, if not able to combine all change atomically, should save 76 // the metadata after the data changes, so that this merge will be re-driven 77 // by sync if is not completely saved during the current run. 78 virtual base::Optional<ModelError> MergeSyncData( 79 std::unique_ptr<MetadataChangeList> metadata_change_list, 80 EntityChangeList entity_data) = 0; 81 82 // Apply changes from the sync server locally. 83 // Please note that |entity_changes| might have fewer entries than 84 // |metadata_change_list| in case when some of the data changes are filtered 85 // out, or even be empty in case when a commit confirmation is processed and 86 // only the metadata needs to persisted. 87 virtual base::Optional<ModelError> ApplySyncChanges( 88 std::unique_ptr<MetadataChangeList> metadata_change_list, 89 EntityChangeList entity_changes) = 0; 90 91 // Asynchronously retrieve the corresponding sync data for |storage_keys|. 92 // |callback| should be invoked if the operation is successful, otherwise 93 // the processor's ReportError method should be called. 94 virtual void GetData(StorageKeyList storage_keys, DataCallback callback) = 0; 95 96 // Asynchronously retrieve all of the local sync data. |callback| should be 97 // invoked if the operation is successful, otherwise the processor's 98 // ReportError method should be called. 99 // Used for getting all data in Sync Node Browser of chrome://sync-internals. 100 virtual void GetAllDataForDebugging(DataCallback callback) = 0; 101 102 // Must not be called unless SupportsGetClientTag() returns true. 103 // 104 // Get or generate a client tag for |entity_data|. This must be the same tag 105 // that was/would have been generated in the SyncableService/Directory world 106 // for backward compatibility with pre-USS clients. The only time this 107 // theoretically needs to be called is on the creation of local data. 108 // 109 // If a model type was never launched pre-USS, then method does not need to be 110 // different from GetStorageKey(). Only the hash of this value is kept. 111 virtual std::string GetClientTag(const EntityData& entity_data) = 0; 112 113 // Must not be called unless SupportsGetStorageKey() returns true. 114 // 115 // Get or generate a storage key for |entity_data|. This will only ever be 116 // called once when first encountering a remote entity. Local changes will 117 // provide their storage keys directly to Put instead of using this method. 118 // Theoretically this function doesn't need to be stable across multiple calls 119 // on the same or different clients, but to keep things simple, it probably 120 // should be. Storage keys are kept in memory at steady state, so each model 121 // type should strive to keep these keys as small as possible. 122 // Returning an empty string means the remote creation should be ignored (i.e. 123 // it contains invalid data). 124 // TODO(crbug.com/1057947): introduce a dedicated method to validate data from 125 // the server to solve the inconsistency with bridges that don't support 126 // GetStorageKey() and with remote updates which are not creations. 127 virtual std::string GetStorageKey(const EntityData& entity_data) = 0; 128 129 // Whether or not the bridge is capable of producing a client tag from 130 // |EntityData| (usually remote changes), via GetClientTag(). Most bridges do, 131 // but in rare cases including commit-only types and read-only types, it may 132 // not. 133 virtual bool SupportsGetClientTag() const; 134 135 // By returning true in this function datatype indicates that it can generate 136 // storage key from EntityData. In this case for all new entities received 137 // from server, change processor will call GetStorageKey and update 138 // EntityChange structures before passing them to MergeSyncData and 139 // ApplySyncChanges. 140 // 141 // This function should return false when datatype's native storage is not 142 // indexed by some combination of values from EntityData, when key into the 143 // storage is obtained at the time the record is inserted into it (e.g. ROWID 144 // in SQLite). In this case entity changes for new entities passed to 145 // MergeSyncData and ApplySyncChanges will have empty storage_key. It is 146 // datatype's responsibility to call UpdateStorageKey for such entities. 147 virtual bool SupportsGetStorageKey() const; 148 149 // By returning true in this function, the datatype indicates that it supports 150 // receiving partial (incremental) updates. If it returns false, the type 151 // indicates that it requires the full data set to be sent to it through 152 // MergeSyncData for any change to the data set. 153 virtual bool SupportsIncrementalUpdates() const; 154 155 // Resolve a conflict between the client and server versions of data. They are 156 // guaranteed not to match (both be deleted or have identical specifics). A 157 // default implementation chooses the server data unless it is a deletion. 158 virtual ConflictResolution ResolveConflict( 159 const std::string& storage_key, 160 const EntityData& remote_data) const; 161 162 // Similar to ApplySyncChanges() but called by the processor when sync 163 // is in the process of being stopped. If |delete_metadata_change_list| is not 164 // null, it indicates that sync metadata must be deleted (i.e. the datatype 165 // was disabled), and |*delete_metadata_change_list| contains a change list to 166 // remove all metadata that the processor knows about (the bridge may decide 167 // to implement deletion by other means). 168 virtual void ApplyStopSyncChanges( 169 std::unique_ptr<MetadataChangeList> delete_metadata_change_list); 170 171 // Called only when some items in a commit haven't been committed due to an 172 // error. 173 virtual void OnCommitAttemptErrors( 174 const syncer::FailedCommitResponseDataList& error_response_list); 175 176 // Called only when a commit failed due to server error. The commit will 177 // automatically be retried, so most implementations don't need to handle 178 // this. 179 virtual void OnCommitAttemptFailed(SyncCommitError commit_error); 180 181 // Returns an estimate of memory usage attributed to sync (that is, excludes 182 // the actual model). Because the resulting UMA metrics are often used to 183 // compare with the non-USS equivalent implementations (SyncableService), it's 184 // a good idea to account for overhead that would also get accounted for the 185 // SyncableService by other means. 186 virtual size_t EstimateSyncOverheadMemoryUsage() const; 187 188 // Needs to be informed about any model change occurring via Delete() and 189 // Put(). The changing metadata should be stored to persistent storage 190 // before or atomically with the model changes. 191 ModelTypeChangeProcessor* change_processor(); 192 const ModelTypeChangeProcessor* change_processor() const; 193 194 private: 195 std::unique_ptr<ModelTypeChangeProcessor> change_processor_; 196 }; 197 198 } // namespace syncer 199 200 #endif // COMPONENTS_SYNC_MODEL_MODEL_TYPE_SYNC_BRIDGE_H_ 201