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 |