| // Copyright 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SYNC_INTERNAL_API_SYNC_MANAGER_H_ |
| #define SYNC_INTERNAL_API_SYNC_MANAGER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "net/base/network_change_notifier.h" |
| #include "sync/base/sync_export.h" |
| #include "sync/engine/all_status.h" |
| #include "sync/engine/net/server_connection_manager.h" |
| #include "sync/engine/sync_engine_event.h" |
| #include "sync/engine/traffic_recorder.h" |
| #include "sync/internal_api/change_reorder_buffer.h" |
| #include "sync/internal_api/debug_info_event_listener.h" |
| #include "sync/internal_api/js_mutation_event_observer.h" |
| #include "sync/internal_api/js_sync_encryption_handler_observer.h" |
| #include "sync/internal_api/js_sync_manager_observer.h" |
| #include "sync/internal_api/public/sync_manager.h" |
| #include "sync/internal_api/public/user_share.h" |
| #include "sync/internal_api/sync_encryption_handler_impl.h" |
| #include "sync/js/js_backend.h" |
| #include "sync/notifier/invalidation_handler.h" |
| #include "sync/notifier/invalidator_state.h" |
| #include "sync/syncable/directory_change_delegate.h" |
| #include "sync/util/cryptographer.h" |
| #include "sync/util/time.h" |
| |
| namespace syncer { |
| |
| class SyncAPIServerConnectionManager; |
| class WriteNode; |
| class WriteTransaction; |
| |
| namespace sessions { |
| class SyncSessionContext; |
| } |
| |
| // SyncManager encapsulates syncable::Directory and serves as the parent of all |
| // other objects in the sync API. If multiple threads interact with the same |
| // local sync repository (i.e. the same sqlite database), they should share a |
| // single SyncManager instance. The caller should typically create one |
| // SyncManager for the lifetime of a user session. |
| // |
| // Unless stated otherwise, all methods of SyncManager should be called on the |
| // same thread. |
| class SYNC_EXPORT_PRIVATE SyncManagerImpl : |
| public SyncManager, |
| public net::NetworkChangeNotifier::IPAddressObserver, |
| public net::NetworkChangeNotifier::ConnectionTypeObserver, |
| public JsBackend, |
| public SyncEngineEventListener, |
| public ServerConnectionEventListener, |
| public syncable::DirectoryChangeDelegate, |
| public SyncEncryptionHandler::Observer { |
| public: |
| // Create an uninitialized SyncManager. Callers must Init() before using. |
| explicit SyncManagerImpl(const std::string& name); |
| virtual ~SyncManagerImpl(); |
| |
| // SyncManager implementation. |
| virtual void Init( |
| const base::FilePath& database_location, |
| const WeakHandle<JsEventHandler>& event_handler, |
| const std::string& sync_server_and_path, |
| int sync_server_port, |
| bool use_ssl, |
| scoped_ptr<HttpPostProviderFactory> post_factory, |
| const std::vector<ModelSafeWorker*>& workers, |
| ExtensionsActivity* extensions_activity, |
| SyncManager::ChangeDelegate* change_delegate, |
| const SyncCredentials& credentials, |
| const std::string& invalidator_client_id, |
| const std::string& restored_key_for_bootstrapping, |
| const std::string& restored_keystore_key_for_bootstrapping, |
| InternalComponentsFactory* internal_components_factory, |
| Encryptor* encryptor, |
| scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler, |
| ReportUnrecoverableErrorFunction |
| report_unrecoverable_error_function, |
| CancelationSignal* cancelation_signal) OVERRIDE; |
| virtual void ThrowUnrecoverableError() OVERRIDE; |
| virtual ModelTypeSet InitialSyncEndedTypes() OVERRIDE; |
| virtual ModelTypeSet GetTypesWithEmptyProgressMarkerToken( |
| ModelTypeSet types) OVERRIDE; |
| virtual bool PurgePartiallySyncedTypes() OVERRIDE; |
| virtual void UpdateCredentials(const SyncCredentials& credentials) OVERRIDE; |
| virtual void StartSyncingNormally( |
| const ModelSafeRoutingInfo& routing_info) OVERRIDE; |
| virtual void ConfigureSyncer( |
| ConfigureReason reason, |
| ModelTypeSet to_download, |
| ModelTypeSet to_purge, |
| ModelTypeSet to_journal, |
| ModelTypeSet to_unapply, |
| const ModelSafeRoutingInfo& new_routing_info, |
| const base::Closure& ready_task, |
| const base::Closure& retry_task) OVERRIDE; |
| virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE; |
| virtual void OnIncomingInvalidation( |
| const ObjectIdInvalidationMap& invalidation_map) OVERRIDE; |
| virtual void AddObserver(SyncManager::Observer* observer) OVERRIDE; |
| virtual void RemoveObserver(SyncManager::Observer* observer) OVERRIDE; |
| virtual SyncStatus GetDetailedStatus() const OVERRIDE; |
| virtual void SaveChanges() OVERRIDE; |
| virtual void ShutdownOnSyncThread() OVERRIDE; |
| virtual UserShare* GetUserShare() OVERRIDE; |
| virtual const std::string cache_guid() OVERRIDE; |
| virtual bool ReceivedExperiment(Experiments* experiments) OVERRIDE; |
| virtual bool HasUnsyncedItems() OVERRIDE; |
| virtual SyncEncryptionHandler* GetEncryptionHandler() OVERRIDE; |
| |
| // SyncEncryptionHandler::Observer implementation. |
| virtual void OnPassphraseRequired( |
| PassphraseRequiredReason reason, |
| const sync_pb::EncryptedData& pending_keys) OVERRIDE; |
| virtual void OnPassphraseAccepted() OVERRIDE; |
| virtual void OnBootstrapTokenUpdated( |
| const std::string& bootstrap_token, |
| BootstrapTokenType type) OVERRIDE; |
| virtual void OnEncryptedTypesChanged( |
| ModelTypeSet encrypted_types, |
| bool encrypt_everything) OVERRIDE; |
| virtual void OnEncryptionComplete() OVERRIDE; |
| virtual void OnCryptographerStateChanged( |
| Cryptographer* cryptographer) OVERRIDE; |
| virtual void OnPassphraseTypeChanged( |
| PassphraseType type, |
| base::Time explicit_passphrase_time) OVERRIDE; |
| |
| static int GetDefaultNudgeDelay(); |
| static int GetPreferencesNudgeDelay(); |
| |
| // SyncEngineEventListener implementation. |
| virtual void OnSyncEngineEvent(const SyncEngineEvent& event) OVERRIDE; |
| |
| // ServerConnectionEventListener implementation. |
| virtual void OnServerConnectionEvent( |
| const ServerConnectionEvent& event) OVERRIDE; |
| |
| // JsBackend implementation. |
| virtual void SetJsEventHandler( |
| const WeakHandle<JsEventHandler>& event_handler) OVERRIDE; |
| virtual void ProcessJsMessage( |
| const std::string& name, const JsArgList& args, |
| const WeakHandle<JsReplyHandler>& reply_handler) OVERRIDE; |
| |
| // DirectoryChangeDelegate implementation. |
| // This listener is called upon completion of a syncable transaction, and |
| // builds the list of sync-engine initiated changes that will be forwarded to |
| // the SyncManager's Observers. |
| virtual void HandleTransactionCompleteChangeEvent( |
| ModelTypeSet models_with_changes) OVERRIDE; |
| virtual ModelTypeSet HandleTransactionEndingChangeEvent( |
| const syncable::ImmutableWriteTransactionInfo& write_transaction_info, |
| syncable::BaseTransaction* trans) OVERRIDE; |
| virtual void HandleCalculateChangesChangeEventFromSyncApi( |
| const syncable::ImmutableWriteTransactionInfo& write_transaction_info, |
| syncable::BaseTransaction* trans, |
| std::vector<int64>* entries_changed) OVERRIDE; |
| virtual void HandleCalculateChangesChangeEventFromSyncer( |
| const syncable::ImmutableWriteTransactionInfo& write_transaction_info, |
| syncable::BaseTransaction* trans, |
| std::vector<int64>* entries_changed) OVERRIDE; |
| |
| // Handle explicit requests to fetch updates for the given types. |
| virtual void RefreshTypes(ModelTypeSet types) OVERRIDE; |
| |
| // These OnYYYChanged() methods are only called by our NetworkChangeNotifier. |
| // Called when IP address of primary interface changes. |
| virtual void OnIPAddressChanged() OVERRIDE; |
| // Called when the connection type of the system has changed. |
| virtual void OnConnectionTypeChanged( |
| net::NetworkChangeNotifier::ConnectionType) OVERRIDE; |
| |
| const SyncScheduler* scheduler() const; |
| |
| bool GetHasInvalidAuthTokenForTest() const; |
| |
| protected: |
| // Helper functions. Virtual for testing. |
| virtual void NotifyInitializationSuccess(); |
| virtual void NotifyInitializationFailure(); |
| |
| private: |
| friend class SyncManagerTest; |
| FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, NudgeDelayTest); |
| FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, OnNotificationStateChange); |
| FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, OnIncomingNotification); |
| FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, PurgeDisabledTypes); |
| FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, PurgeUnappliedTypes); |
| |
| struct NotificationInfo { |
| NotificationInfo(); |
| ~NotificationInfo(); |
| |
| int total_count; |
| std::string payload; |
| |
| // Returned pointer owned by the caller. |
| base::DictionaryValue* ToValue() const; |
| }; |
| |
| base::TimeDelta GetNudgeDelayTimeDelta(const ModelType& model_type); |
| |
| typedef std::map<ModelType, NotificationInfo> NotificationInfoMap; |
| typedef JsArgList (SyncManagerImpl::*UnboundJsMessageHandler)( |
| const JsArgList&); |
| typedef base::Callback<JsArgList(const JsArgList&)> JsMessageHandler; |
| typedef std::map<std::string, JsMessageHandler> JsMessageHandlerMap; |
| |
| // Determine if the parents or predecessors differ between the old and new |
| // versions of an entry. Note that a node's index may change without its |
| // UNIQUE_POSITION changing if its sibling nodes were changed. To handle such |
| // cases, we rely on the caller to treat a position update on any sibling as |
| // updating the positions of all siblings. |
| bool VisiblePositionsDiffer( |
| const syncable::EntryKernelMutation& mutation) const; |
| |
| // Determine if any of the fields made visible to clients of the Sync API |
| // differ between the versions of an entry stored in |a| and |b|. A return |
| // value of false means that it should be OK to ignore this change. |
| bool VisiblePropertiesDiffer( |
| const syncable::EntryKernelMutation& mutation, |
| Cryptographer* cryptographer) const; |
| |
| // Open the directory named with |username|. |
| bool OpenDirectory(const std::string& username); |
| |
| // Purge those disabled types as specified by |to_purge|. |to_journal| and |
| // |to_unapply| specify subsets that require special handling. |to_journal| |
| // types are saved into the delete journal, while |to_unapply| have only |
| // their local data deleted, while their server data is preserved. |
| bool PurgeDisabledTypes(ModelTypeSet to_purge, |
| ModelTypeSet to_journal, |
| ModelTypeSet to_unapply); |
| |
| void RequestNudgeForDataTypes( |
| const tracked_objects::Location& nudge_location, |
| ModelTypeSet type); |
| |
| // If this is a deletion for a password, sets the legacy |
| // ExtraPasswordChangeRecordData field of |buffer|. Otherwise sets |
| // |buffer|'s specifics field to contain the unencrypted data. |
| void SetExtraChangeRecordData(int64 id, |
| ModelType type, |
| ChangeReorderBuffer* buffer, |
| Cryptographer* cryptographer, |
| const syncable::EntryKernel& original, |
| bool existed_before, |
| bool exists_now); |
| |
| // Called for every notification. This updates the notification statistics |
| // to be displayed in about:sync. |
| void UpdateNotificationInfo(const ObjectIdInvalidationMap& invalidation_map); |
| |
| // Checks for server reachabilty and requests a nudge. |
| void OnNetworkConnectivityChangedImpl(); |
| |
| // Helper function used only by the constructor. |
| void BindJsMessageHandler( |
| const std::string& name, UnboundJsMessageHandler unbound_message_handler); |
| |
| // Returned pointer is owned by the caller. |
| static base::DictionaryValue* NotificationInfoToValue( |
| const NotificationInfoMap& notification_info); |
| |
| static std::string NotificationInfoToString( |
| const NotificationInfoMap& notification_info); |
| |
| // JS message handlers. |
| JsArgList GetNotificationState(const JsArgList& args); |
| JsArgList GetNotificationInfo(const JsArgList& args); |
| JsArgList GetRootNodeDetails(const JsArgList& args); |
| JsArgList GetAllNodes(const JsArgList& args); |
| JsArgList GetNodeSummariesById(const JsArgList& args); |
| JsArgList GetNodeDetailsById(const JsArgList& args); |
| JsArgList GetChildNodeIds(const JsArgList& args); |
| JsArgList GetClientServerTraffic(const JsArgList& args); |
| |
| syncable::Directory* directory(); |
| |
| base::FilePath database_path_; |
| |
| const std::string name_; |
| |
| base::ThreadChecker thread_checker_; |
| |
| // Thread-safe handle used by |
| // HandleCalculateChangesChangeEventFromSyncApi(), which can be |
| // called from any thread. Valid only between between calls to |
| // Init() and Shutdown(). |
| // |
| // TODO(akalin): Ideally, we wouldn't need to store this; instead, |
| // we'd have another worker class which implements |
| // HandleCalculateChangesChangeEventFromSyncApi() and we'd pass it a |
| // WeakHandle when we construct it. |
| WeakHandle<SyncManagerImpl> weak_handle_this_; |
| |
| // We give a handle to share_ to clients of the API for use when constructing |
| // any transaction type. |
| UserShare share_; |
| |
| // This can be called from any thread, but only between calls to |
| // OpenDirectory() and ShutdownOnSyncThread(). |
| WeakHandle<SyncManager::ChangeObserver> change_observer_; |
| |
| ObserverList<SyncManager::Observer> observers_; |
| |
| // The ServerConnectionManager used to abstract communication between the |
| // client (the Syncer) and the sync server. |
| scoped_ptr<SyncAPIServerConnectionManager> connection_manager_; |
| |
| // A container of various bits of information used by the SyncScheduler to |
| // create SyncSessions. Must outlive the SyncScheduler. |
| scoped_ptr<sessions::SyncSessionContext> session_context_; |
| |
| // The scheduler that runs the Syncer. Needs to be explicitly |
| // Start()ed. |
| scoped_ptr<SyncScheduler> scheduler_; |
| |
| // A multi-purpose status watch object that aggregates stats from various |
| // sync components. |
| AllStatus allstatus_; |
| |
| // Each element of this map is a store of change records produced by |
| // HandleChangeEventFromSyncer during the CALCULATE_CHANGES step. The changes |
| // are grouped by model type, and are stored here in tree order to be |
| // forwarded to the observer slightly later, at the TRANSACTION_ENDING step |
| // by HandleTransactionEndingChangeEvent. The list is cleared after observer |
| // finishes processing. |
| typedef std::map<int, ImmutableChangeRecordList> ChangeRecordMap; |
| ChangeRecordMap change_records_; |
| |
| SyncManager::ChangeDelegate* change_delegate_; |
| |
| // Set to true once Init has been called. |
| bool initialized_; |
| |
| bool observing_network_connectivity_changes_; |
| |
| InvalidatorState invalidator_state_; |
| |
| // Map used to store the notification info to be displayed in |
| // about:sync page. |
| NotificationInfoMap notification_info_map_; |
| |
| // These are for interacting with chrome://sync-internals. |
| JsMessageHandlerMap js_message_handlers_; |
| WeakHandle<JsEventHandler> js_event_handler_; |
| JsSyncManagerObserver js_sync_manager_observer_; |
| JsMutationEventObserver js_mutation_event_observer_; |
| JsSyncEncryptionHandlerObserver js_sync_encryption_handler_observer_; |
| |
| // This is for keeping track of client events to send to the server. |
| DebugInfoEventListener debug_info_event_listener_; |
| |
| TrafficRecorder traffic_recorder_; |
| |
| Encryptor* encryptor_; |
| scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler_; |
| ReportUnrecoverableErrorFunction report_unrecoverable_error_function_; |
| |
| // Sync's encryption handler. It tracks the set of encrypted types, manages |
| // changing passphrases, and in general handles sync-specific interactions |
| // with the cryptographer. |
| scoped_ptr<SyncEncryptionHandlerImpl> sync_encryption_handler_; |
| |
| base::WeakPtrFactory<SyncManagerImpl> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SyncManagerImpl); |
| }; |
| |
| } // namespace syncer |
| |
| #endif // SYNC_INTERNAL_API_SYNC_MANAGER_H_ |