| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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_MODEL_TYPE_WORKER_H_ | |
| 6 #define SYNC_ENGINE_MODEL_TYPE_WORKER_H_ | |
| 7 | |
| 8 #include <stddef.h> | |
| 9 | |
| 10 #include <map> | |
| 11 #include <memory> | |
| 12 #include <string> | |
| 13 | |
| 14 #include "base/memory/weak_ptr.h" | |
| 15 #include "base/threading/non_thread_safe.h" | |
| 16 #include "sync/base/sync_export.h" | |
| 17 #include "sync/engine/commit_contributor.h" | |
| 18 #include "sync/engine/commit_queue.h" | |
| 19 #include "sync/engine/nudge_handler.h" | |
| 20 #include "sync/engine/update_handler.h" | |
| 21 #include "sync/internal_api/public/base/model_type.h" | |
| 22 #include "sync/internal_api/public/non_blocking_sync_common.h" | |
| 23 #include "sync/internal_api/public/sync_encryption_handler.h" | |
| 24 #include "sync/protocol/data_type_state.pb.h" | |
| 25 #include "sync/protocol/sync.pb.h" | |
| 26 #include "sync/util/cryptographer.h" | |
| 27 | |
| 28 namespace base { | |
| 29 class SingleThreadTaskRunner; | |
| 30 } | |
| 31 | |
| 32 namespace syncer_v2 { | |
| 33 | |
| 34 class ModelTypeProcessor; | |
| 35 class WorkerEntityTracker; | |
| 36 | |
| 37 // A smart cache for sync types that use message passing (rather than | |
| 38 // transactions and the syncable::Directory) to communicate with the sync | |
| 39 // thread. | |
| 40 // | |
| 41 // When the non-blocking sync type wants to talk with the sync server, it will | |
| 42 // send a message from its thread to this object on the sync thread. This | |
| 43 // object ensures the appropriate sync server communication gets scheduled and | |
| 44 // executed. The response, if any, will be returned to the non-blocking sync | |
| 45 // type's thread eventually. | |
| 46 // | |
| 47 // This object also has a role to play in communications in the opposite | |
| 48 // direction. Sometimes the sync thread will receive changes from the sync | |
| 49 // server and deliver them here. This object will post this information back to | |
| 50 // the appropriate component on the model type's thread. | |
| 51 // | |
| 52 // This object does more than just pass along messages. It understands the sync | |
| 53 // protocol, and it can make decisions when it sees conflicting messages. For | |
| 54 // example, if the sync server sends down an update for a sync entity that is | |
| 55 // currently pending for commit, this object will detect this condition and | |
| 56 // cancel the pending commit. | |
| 57 class SYNC_EXPORT ModelTypeWorker : public syncer::UpdateHandler, | |
| 58 public syncer::CommitContributor, | |
| 59 public CommitQueue, | |
| 60 public base::NonThreadSafe { | |
| 61 public: | |
| 62 ModelTypeWorker(syncer::ModelType type, | |
| 63 const sync_pb::DataTypeState& initial_state, | |
| 64 std::unique_ptr<syncer::Cryptographer> cryptographer, | |
| 65 syncer::NudgeHandler* nudge_handler, | |
| 66 std::unique_ptr<ModelTypeProcessor> model_type_processor); | |
| 67 ~ModelTypeWorker() override; | |
| 68 | |
| 69 syncer::ModelType GetModelType() const; | |
| 70 | |
| 71 bool IsEncryptionRequired() const; | |
| 72 void UpdateCryptographer( | |
| 73 std::unique_ptr<syncer::Cryptographer> cryptographer); | |
| 74 | |
| 75 // UpdateHandler implementation. | |
| 76 bool IsInitialSyncEnded() const override; | |
| 77 void GetDownloadProgress( | |
| 78 sync_pb::DataTypeProgressMarker* progress_marker) const override; | |
| 79 void GetDataTypeContext(sync_pb::DataTypeContext* context) const override; | |
| 80 syncer::SyncerError ProcessGetUpdatesResponse( | |
| 81 const sync_pb::DataTypeProgressMarker& progress_marker, | |
| 82 const sync_pb::DataTypeContext& mutated_context, | |
| 83 const SyncEntityList& applicable_updates, | |
| 84 syncer::sessions::StatusController* status) override; | |
| 85 void ApplyUpdates(syncer::sessions::StatusController* status) override; | |
| 86 void PassiveApplyUpdates(syncer::sessions::StatusController* status) override; | |
| 87 | |
| 88 // CommitQueue implementation. | |
| 89 void EnqueueForCommit(const CommitRequestDataList& request_list) override; | |
| 90 | |
| 91 // CommitContributor implementation. | |
| 92 std::unique_ptr<syncer::CommitContribution> GetContribution( | |
| 93 size_t max_entries) override; | |
| 94 | |
| 95 // Callback for when our contribution gets a response. | |
| 96 void OnCommitResponse(CommitResponseDataList* response_list); | |
| 97 | |
| 98 base::WeakPtr<ModelTypeWorker> AsWeakPtr(); | |
| 99 | |
| 100 private: | |
| 101 using EntityMap = std::map<std::string, std::unique_ptr<WorkerEntityTracker>>; | |
| 102 | |
| 103 // Helper function to actually send |pending_updates_| to the processor. | |
| 104 void ApplyPendingUpdates(); | |
| 105 | |
| 106 // Returns true if this type has successfully fetched all available updates | |
| 107 // from the server at least once. Our state may or may not be stale, but at | |
| 108 // least we know that it was valid at some point in the past. | |
| 109 bool IsTypeInitialized() const; | |
| 110 | |
| 111 // Returns true if this type is prepared to commit items. Currently, this | |
| 112 // depends on having downloaded the initial data and having the encryption | |
| 113 // settings in a good state. | |
| 114 bool CanCommitItems() const; | |
| 115 | |
| 116 // Takes |commit_entity| populated from fields of WorkerEntityTracker and | |
| 117 // adjusts some fields before committing to server. Adjustments include | |
| 118 // generating client-assigned ID, encrypting data, etc. | |
| 119 void AdjustCommitProto(sync_pb::SyncEntity* commit_entity); | |
| 120 | |
| 121 // Attempts to decrypt encrypted updates stored in the EntityMap. If | |
| 122 // successful, will remove the update from the its tracker and forward | |
| 123 // it to the processor for application. Will forward any new encryption | |
| 124 // keys to the processor to trigger re-encryption if necessary. | |
| 125 void OnCryptographerUpdated(); | |
| 126 | |
| 127 // Attempts to decrypt the given specifics and return them in the |out| | |
| 128 // parameter. Assumes cryptographer->CanDecrypt(specifics) returned true. | |
| 129 // | |
| 130 // Returns false if the decryption failed. There are no guarantees about the | |
| 131 // contents of |out| when that happens. | |
| 132 // | |
| 133 // In theory, this should never fail. Only corrupt or invalid entries could | |
| 134 // cause this to fail, and no clients are known to create such entries. The | |
| 135 // failure case is an attempt to be defensive against bad input. | |
| 136 static bool DecryptSpecifics(syncer::Cryptographer* cryptographer, | |
| 137 const sync_pb::EntitySpecifics& in, | |
| 138 sync_pb::EntitySpecifics* out); | |
| 139 | |
| 140 // Returns the entity tracker for the given |tag_hash|, or nullptr. | |
| 141 WorkerEntityTracker* GetEntityTracker(const std::string& tag_hash); | |
| 142 | |
| 143 // Creates an entity tracker in the map using the given |data| and returns a | |
| 144 // pointer to it. Requires that one doesn't exist for data.client_tag_hash. | |
| 145 WorkerEntityTracker* CreateEntityTracker(const EntityData& data); | |
| 146 | |
| 147 // Gets the entity tracker for |data| or creates one if it doesn't exist. | |
| 148 WorkerEntityTracker* GetOrCreateEntityTracker(const EntityData& data); | |
| 149 | |
| 150 syncer::ModelType type_; | |
| 151 | |
| 152 // State that applies to the entire model type. | |
| 153 sync_pb::DataTypeState data_type_state_; | |
| 154 | |
| 155 // Pointer to the ModelTypeProcessor associated with this worker. Never null. | |
| 156 std::unique_ptr<ModelTypeProcessor> model_type_processor_; | |
| 157 | |
| 158 // A private copy of the most recent cryptographer known to sync. | |
| 159 // Initialized at construction time and updated with UpdateCryptographer(). | |
| 160 // NULL if encryption is not enabled for this type. | |
| 161 std::unique_ptr<syncer::Cryptographer> cryptographer_; | |
| 162 | |
| 163 // Interface used to access and send nudges to the sync scheduler. Not owned. | |
| 164 syncer::NudgeHandler* nudge_handler_; | |
| 165 | |
| 166 // A map of per-entity information known to this object. | |
| 167 // | |
| 168 // When commits are pending, their information is stored here. This | |
| 169 // information is dropped from memory when the commit succeeds or gets | |
| 170 // cancelled. | |
| 171 // | |
| 172 // This also stores some information related to received server state in | |
| 173 // order to implement reflection blocking and conflict detection. This | |
| 174 // information is kept in memory indefinitely. With a bit more coordination | |
| 175 // with the model thread, we could optimize this to reduce memory usage in | |
| 176 // the steady state. | |
| 177 EntityMap entities_; | |
| 178 | |
| 179 // Accumulates all the updates from a single GetUpdates cycle in memory so | |
| 180 // they can all be sent to the processor at once. | |
| 181 UpdateResponseDataList pending_updates_; | |
| 182 | |
| 183 base::WeakPtrFactory<ModelTypeWorker> weak_ptr_factory_; | |
| 184 }; | |
| 185 | |
| 186 } // namespace syncer_v2 | |
| 187 | |
| 188 #endif // SYNC_ENGINE_MODEL_TYPE_WORKER_H_ | |
| OLD | NEW |