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