1 // Copyright 2012 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_INTERNAL_API_SYNC_MANAGER_H_ 6 #define SYNC_INTERNAL_API_SYNC_MANAGER_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "net/base/network_change_notifier.h" 12 #include "sync/base/sync_export.h" 13 #include "sync/engine/all_status.h" 14 #include "sync/engine/net/server_connection_manager.h" 15 #include "sync/engine/sync_engine_event.h" 16 #include "sync/engine/traffic_recorder.h" 17 #include "sync/internal_api/change_reorder_buffer.h" 18 #include "sync/internal_api/debug_info_event_listener.h" 19 #include "sync/internal_api/js_mutation_event_observer.h" 20 #include "sync/internal_api/js_sync_encryption_handler_observer.h" 21 #include "sync/internal_api/js_sync_manager_observer.h" 22 #include "sync/internal_api/public/sync_manager.h" 23 #include "sync/internal_api/public/user_share.h" 24 #include "sync/internal_api/sync_encryption_handler_impl.h" 25 #include "sync/js/js_backend.h" 26 #include "sync/notifier/invalidation_handler.h" 27 #include "sync/notifier/invalidator_state.h" 28 #include "sync/syncable/directory_change_delegate.h" 29 #include "sync/util/cryptographer.h" 30 #include "sync/util/time.h" 31 32 namespace syncer { 33 34 class SyncAPIServerConnectionManager; 35 class WriteNode; 36 class WriteTransaction; 37 38 namespace sessions { 39 class SyncSessionContext; 40 } 41 42 // SyncManager encapsulates syncable::Directory and serves as the parent of all 43 // other objects in the sync API. If multiple threads interact with the same 44 // local sync repository (i.e. the same sqlite database), they should share a 45 // single SyncManager instance. The caller should typically create one 46 // SyncManager for the lifetime of a user session. 47 // 48 // Unless stated otherwise, all methods of SyncManager should be called on the 49 // same thread. 50 class SYNC_EXPORT_PRIVATE SyncManagerImpl : 51 public SyncManager, 52 public net::NetworkChangeNotifier::IPAddressObserver, 53 public net::NetworkChangeNotifier::ConnectionTypeObserver, 54 public JsBackend, 55 public SyncEngineEventListener, 56 public ServerConnectionEventListener, 57 public syncable::DirectoryChangeDelegate, 58 public SyncEncryptionHandler::Observer { 59 public: 60 // Create an uninitialized SyncManager. Callers must Init() before using. 61 explicit SyncManagerImpl(const std::string& name); 62 virtual ~SyncManagerImpl(); 63 64 // SyncManager implementation. 65 virtual void Init( 66 const base::FilePath& database_location, 67 const WeakHandle<JsEventHandler>& event_handler, 68 const std::string& sync_server_and_path, 69 int sync_server_port, 70 bool use_ssl, 71 scoped_ptr<HttpPostProviderFactory> post_factory, 72 const std::vector<ModelSafeWorker*>& workers, 73 ExtensionsActivity* extensions_activity, 74 SyncManager::ChangeDelegate* change_delegate, 75 const SyncCredentials& credentials, 76 const std::string& invalidator_client_id, 77 const std::string& restored_key_for_bootstrapping, 78 const std::string& restored_keystore_key_for_bootstrapping, 79 InternalComponentsFactory* internal_components_factory, 80 Encryptor* encryptor, 81 scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler, 82 ReportUnrecoverableErrorFunction 83 report_unrecoverable_error_function, 84 bool use_oauth2_token) OVERRIDE; 85 virtual void ThrowUnrecoverableError() OVERRIDE; 86 virtual ModelTypeSet InitialSyncEndedTypes() OVERRIDE; 87 virtual ModelTypeSet GetTypesWithEmptyProgressMarkerToken( 88 ModelTypeSet types) OVERRIDE; 89 virtual bool PurgePartiallySyncedTypes() OVERRIDE; 90 virtual void UpdateCredentials(const SyncCredentials& credentials) OVERRIDE; 91 virtual void StartSyncingNormally( 92 const ModelSafeRoutingInfo& routing_info) OVERRIDE; 93 virtual void ConfigureSyncer( 94 ConfigureReason reason, 95 ModelTypeSet to_download, 96 ModelTypeSet to_purge, 97 ModelTypeSet to_journal, 98 ModelTypeSet to_unapply, 99 const ModelSafeRoutingInfo& new_routing_info, 100 const base::Closure& ready_task, 101 const base::Closure& retry_task) OVERRIDE; 102 virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE; 103 virtual void OnIncomingInvalidation( 104 const ObjectIdInvalidationMap& invalidation_map) OVERRIDE; 105 virtual void AddObserver(SyncManager::Observer* observer) OVERRIDE; 106 virtual void RemoveObserver(SyncManager::Observer* observer) OVERRIDE; 107 virtual SyncStatus GetDetailedStatus() const OVERRIDE; 108 virtual void SaveChanges() OVERRIDE; 109 virtual void StopSyncingForShutdown() OVERRIDE; 110 virtual void ShutdownOnSyncThread() OVERRIDE; 111 virtual UserShare* GetUserShare() OVERRIDE; 112 virtual const std::string cache_guid() OVERRIDE; 113 virtual bool ReceivedExperiment(Experiments* experiments) OVERRIDE; 114 virtual bool HasUnsyncedItems() OVERRIDE; 115 virtual SyncEncryptionHandler* GetEncryptionHandler() OVERRIDE; 116 117 // SyncEncryptionHandler::Observer implementation. 118 virtual void OnPassphraseRequired( 119 PassphraseRequiredReason reason, 120 const sync_pb::EncryptedData& pending_keys) OVERRIDE; 121 virtual void OnPassphraseAccepted() OVERRIDE; 122 virtual void OnBootstrapTokenUpdated( 123 const std::string& bootstrap_token, 124 BootstrapTokenType type) OVERRIDE; 125 virtual void OnEncryptedTypesChanged( 126 ModelTypeSet encrypted_types, 127 bool encrypt_everything) OVERRIDE; 128 virtual void OnEncryptionComplete() OVERRIDE; 129 virtual void OnCryptographerStateChanged( 130 Cryptographer* cryptographer) OVERRIDE; 131 virtual void OnPassphraseTypeChanged( 132 PassphraseType type, 133 base::Time explicit_passphrase_time) OVERRIDE; 134 135 static int GetDefaultNudgeDelay(); 136 static int GetPreferencesNudgeDelay(); 137 138 // SyncEngineEventListener implementation. 139 virtual void OnSyncEngineEvent(const SyncEngineEvent& event) OVERRIDE; 140 141 // ServerConnectionEventListener implementation. 142 virtual void OnServerConnectionEvent( 143 const ServerConnectionEvent& event) OVERRIDE; 144 145 // JsBackend implementation. 146 virtual void SetJsEventHandler( 147 const WeakHandle<JsEventHandler>& event_handler) OVERRIDE; 148 virtual void ProcessJsMessage( 149 const std::string& name, const JsArgList& args, 150 const WeakHandle<JsReplyHandler>& reply_handler) OVERRIDE; 151 152 // DirectoryChangeDelegate implementation. 153 // This listener is called upon completion of a syncable transaction, and 154 // builds the list of sync-engine initiated changes that will be forwarded to 155 // the SyncManager's Observers. 156 virtual void HandleTransactionCompleteChangeEvent( 157 ModelTypeSet models_with_changes) OVERRIDE; 158 virtual ModelTypeSet HandleTransactionEndingChangeEvent( 159 const syncable::ImmutableWriteTransactionInfo& write_transaction_info, 160 syncable::BaseTransaction* trans) OVERRIDE; 161 virtual void HandleCalculateChangesChangeEventFromSyncApi( 162 const syncable::ImmutableWriteTransactionInfo& write_transaction_info, 163 syncable::BaseTransaction* trans, 164 std::vector<int64>* entries_changed) OVERRIDE; 165 virtual void HandleCalculateChangesChangeEventFromSyncer( 166 const syncable::ImmutableWriteTransactionInfo& write_transaction_info, 167 syncable::BaseTransaction* trans, 168 std::vector<int64>* entries_changed) OVERRIDE; 169 170 // Handle explicit requests to fetch updates for the given types. 171 virtual void RefreshTypes(ModelTypeSet types) OVERRIDE; 172 173 // These OnYYYChanged() methods are only called by our NetworkChangeNotifier. 174 // Called when IP address of primary interface changes. 175 virtual void OnIPAddressChanged() OVERRIDE; 176 // Called when the connection type of the system has changed. 177 virtual void OnConnectionTypeChanged( 178 net::NetworkChangeNotifier::ConnectionType) OVERRIDE; 179 180 const SyncScheduler* scheduler() const; 181 182 bool GetHasInvalidAuthTokenForTest() const; 183 184 private: 185 friend class SyncManagerTest; 186 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, NudgeDelayTest); 187 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, OnNotificationStateChange); 188 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, OnIncomingNotification); 189 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, PurgeDisabledTypes); 190 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, PurgeUnappliedTypes); 191 192 struct NotificationInfo { 193 NotificationInfo(); 194 ~NotificationInfo(); 195 196 int total_count; 197 std::string payload; 198 199 // Returned pointer owned by the caller. 200 base::DictionaryValue* ToValue() const; 201 }; 202 203 base::TimeDelta GetNudgeDelayTimeDelta(const ModelType& model_type); 204 205 typedef std::map<ModelType, NotificationInfo> NotificationInfoMap; 206 typedef JsArgList (SyncManagerImpl::*UnboundJsMessageHandler)( 207 const JsArgList&); 208 typedef base::Callback<JsArgList(const JsArgList&)> JsMessageHandler; 209 typedef std::map<std::string, JsMessageHandler> JsMessageHandlerMap; 210 211 // Determine if the parents or predecessors differ between the old and new 212 // versions of an entry. Note that a node's index may change without its 213 // UNIQUE_POSITION changing if its sibling nodes were changed. To handle such 214 // cases, we rely on the caller to treat a position update on any sibling as 215 // updating the positions of all siblings. 216 bool VisiblePositionsDiffer( 217 const syncable::EntryKernelMutation& mutation) const; 218 219 // Determine if any of the fields made visible to clients of the Sync API 220 // differ between the versions of an entry stored in |a| and |b|. A return 221 // value of false means that it should be OK to ignore this change. 222 bool VisiblePropertiesDiffer( 223 const syncable::EntryKernelMutation& mutation, 224 Cryptographer* cryptographer) const; 225 226 // Open the directory named with |username|. 227 bool OpenDirectory(const std::string& username); 228 229 // Purge those disabled types as specified by |to_purge|. |to_journal| and 230 // |to_unapply| specify subsets that require special handling. |to_journal| 231 // types are saved into the delete journal, while |to_unapply| have only 232 // their local data deleted, while their server data is preserved. 233 bool PurgeDisabledTypes(ModelTypeSet to_purge, 234 ModelTypeSet to_journal, 235 ModelTypeSet to_unapply); 236 237 void RequestNudgeForDataTypes( 238 const tracked_objects::Location& nudge_location, 239 ModelTypeSet type); 240 241 // If this is a deletion for a password, sets the legacy 242 // ExtraPasswordChangeRecordData field of |buffer|. Otherwise sets 243 // |buffer|'s specifics field to contain the unencrypted data. 244 void SetExtraChangeRecordData(int64 id, 245 ModelType type, 246 ChangeReorderBuffer* buffer, 247 Cryptographer* cryptographer, 248 const syncable::EntryKernel& original, 249 bool existed_before, 250 bool exists_now); 251 252 // Called for every notification. This updates the notification statistics 253 // to be displayed in about:sync. 254 void UpdateNotificationInfo( 255 const ModelTypeInvalidationMap& invalidation_map); 256 257 // Checks for server reachabilty and requests a nudge. 258 void OnNetworkConnectivityChangedImpl(); 259 260 // Helper function used only by the constructor. 261 void BindJsMessageHandler( 262 const std::string& name, UnboundJsMessageHandler unbound_message_handler); 263 264 // Returned pointer is owned by the caller. 265 static base::DictionaryValue* NotificationInfoToValue( 266 const NotificationInfoMap& notification_info); 267 268 static std::string NotificationInfoToString( 269 const NotificationInfoMap& notification_info); 270 271 // JS message handlers. 272 JsArgList GetNotificationState(const JsArgList& args); 273 JsArgList GetNotificationInfo(const JsArgList& args); 274 JsArgList GetRootNodeDetails(const JsArgList& args); 275 JsArgList GetAllNodes(const JsArgList& args); 276 JsArgList GetNodeSummariesById(const JsArgList& args); 277 JsArgList GetNodeDetailsById(const JsArgList& args); 278 JsArgList GetChildNodeIds(const JsArgList& args); 279 JsArgList GetClientServerTraffic(const JsArgList& args); 280 281 syncable::Directory* directory(); 282 283 base::FilePath database_path_; 284 285 const std::string name_; 286 287 base::ThreadChecker thread_checker_; 288 289 base::WeakPtrFactory<SyncManagerImpl> weak_ptr_factory_; 290 291 // Thread-safe handle used by 292 // HandleCalculateChangesChangeEventFromSyncApi(), which can be 293 // called from any thread. Valid only between between calls to 294 // Init() and Shutdown(). 295 // 296 // TODO(akalin): Ideally, we wouldn't need to store this; instead, 297 // we'd have another worker class which implements 298 // HandleCalculateChangesChangeEventFromSyncApi() and we'd pass it a 299 // WeakHandle when we construct it. 300 WeakHandle<SyncManagerImpl> weak_handle_this_; 301 302 // We give a handle to share_ to clients of the API for use when constructing 303 // any transaction type. 304 UserShare share_; 305 306 // This can be called from any thread, but only between calls to 307 // OpenDirectory() and ShutdownOnSyncThread(). 308 WeakHandle<SyncManager::ChangeObserver> change_observer_; 309 310 ObserverList<SyncManager::Observer> observers_; 311 312 // The ServerConnectionManager used to abstract communication between the 313 // client (the Syncer) and the sync server. 314 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_; 315 316 // A container of various bits of information used by the SyncScheduler to 317 // create SyncSessions. Must outlive the SyncScheduler. 318 scoped_ptr<sessions::SyncSessionContext> session_context_; 319 320 // The scheduler that runs the Syncer. Needs to be explicitly 321 // Start()ed. 322 scoped_ptr<SyncScheduler> scheduler_; 323 324 // A multi-purpose status watch object that aggregates stats from various 325 // sync components. 326 AllStatus allstatus_; 327 328 // Each element of this map is a store of change records produced by 329 // HandleChangeEventFromSyncer during the CALCULATE_CHANGES step. The changes 330 // are grouped by model type, and are stored here in tree order to be 331 // forwarded to the observer slightly later, at the TRANSACTION_ENDING step 332 // by HandleTransactionEndingChangeEvent. The list is cleared after observer 333 // finishes processing. 334 typedef std::map<int, ImmutableChangeRecordList> ChangeRecordMap; 335 ChangeRecordMap change_records_; 336 337 SyncManager::ChangeDelegate* change_delegate_; 338 339 // Set to true once Init has been called. 340 bool initialized_; 341 342 bool observing_network_connectivity_changes_; 343 344 InvalidatorState invalidator_state_; 345 346 // Map used to store the notification info to be displayed in 347 // about:sync page. 348 NotificationInfoMap notification_info_map_; 349 350 // These are for interacting with chrome://sync-internals. 351 JsMessageHandlerMap js_message_handlers_; 352 WeakHandle<JsEventHandler> js_event_handler_; 353 JsSyncManagerObserver js_sync_manager_observer_; 354 JsMutationEventObserver js_mutation_event_observer_; 355 JsSyncEncryptionHandlerObserver js_sync_encryption_handler_observer_; 356 357 // This is for keeping track of client events to send to the server. 358 DebugInfoEventListener debug_info_event_listener_; 359 360 TrafficRecorder traffic_recorder_; 361 362 Encryptor* encryptor_; 363 scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler_; 364 ReportUnrecoverableErrorFunction report_unrecoverable_error_function_; 365 366 // Sync's encryption handler. It tracks the set of encrypted types, manages 367 // changing passphrases, and in general handles sync-specific interactions 368 // with the cryptographer. 369 scoped_ptr<SyncEncryptionHandlerImpl> sync_encryption_handler_; 370 371 DISALLOW_COPY_AND_ASSIGN(SyncManagerImpl); 372 }; 373 374 } // namespace syncer 375 376 #endif // SYNC_INTERNAL_API_SYNC_MANAGER_H_ 377