// Copyright 2014 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__ #define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__ #include "components/sync_driver/data_type_manager.h" #include #include #include #include "base/basictypes.h" #include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "components/sync_driver/backend_data_type_configurer.h" #include "components/sync_driver/model_association_manager.h" namespace syncer { struct DataTypeConfigurationStats; class DataTypeDebugInfoListener; template class WeakHandle; } namespace sync_driver { class DataTypeController; class DataTypeEncryptionHandler; class DataTypeManagerObserver; // List of data types grouped by priority and ordered from high priority to // low priority. typedef std::queue TypeSetPriorityList; class DataTypeManagerImpl : public DataTypeManager, public ModelAssociationManagerDelegate { public: DataTypeManagerImpl( const base::Closure& unrecoverable_error_method, const syncer::WeakHandle& debug_info_listener, const DataTypeController::TypeMap* controllers, const DataTypeEncryptionHandler* encryption_handler, BackendDataTypeConfigurer* configurer, DataTypeManagerObserver* observer); ~DataTypeManagerImpl() override; // DataTypeManager interface. void Configure(syncer::ModelTypeSet desired_types, syncer::ConfigureReason reason) override; void ReenableType(syncer::ModelType type) override; void ResetDataTypeErrors() override; // Needed only for backend migration. void PurgeForMigration(syncer::ModelTypeSet undesired_types, syncer::ConfigureReason reason) override; void Stop() override; State state() const override; // |ModelAssociationManagerDelegate| implementation. void OnSingleDataTypeAssociationDone( syncer::ModelType type, const syncer::DataTypeAssociationStats& association_stats) override; void OnModelAssociationDone( const DataTypeManager::ConfigureResult& result) override; void OnSingleDataTypeWillStop(syncer::ModelType type, const syncer::SyncError& error) override; // Used by unit tests. TODO(sync) : This would go away if we made // this class be able to do Dependency injection. crbug.com/129212. ModelAssociationManager* GetModelAssociationManagerForTesting() { return &model_association_manager_; } private: // Helper enum for identifying which types within a priority group to // associate. enum AssociationGroup { // Those types that were already downloaded and didn't have an error at // configuration time. Corresponds with AssociationTypesInfo's // |ready_types|. These types can start associating as soon as the // ModelAssociationManager is not busy. READY_AT_CONFIG, // All other types, including first time sync types and those that have // encountered an error. These types must wait until the syncer has done // any db changes and/or downloads before associating. UNREADY_AT_CONFIG, }; friend class TestDataTypeManager; // Abort configuration and stop all data types due to configuration errors. void Abort(ConfigureStatus status); // Returns the priority types (control + priority user types). // Virtual for overriding during tests. virtual syncer::ModelTypeSet GetPriorityTypes() const; // Divide |types| into sets by their priorities and return the sets from // high priority to low priority. TypeSetPriorityList PrioritizeTypes(const syncer::ModelTypeSet& types); // Post a task to reconfigure when no downloading or association are running. void ProcessReconfigure(); void Restart(syncer::ConfigureReason reason); void DownloadReady(syncer::ModelTypeSet types_to_download, syncer::ModelTypeSet first_sync_types, syncer::ModelTypeSet failed_configuration_types); // Notification from the SBH that download failed due to a transient // error and it will be retried. void OnDownloadRetry(); void NotifyStart(); void NotifyDone(const ConfigureResult& result); // Add to |configure_time_delta_| the time since we last called // Restart(). void AddToConfigureTime(); void ConfigureImpl(syncer::ModelTypeSet desired_types, syncer::ConfigureReason reason); BackendDataTypeConfigurer::DataTypeConfigStateMap BuildDataTypeConfigStateMap( const syncer::ModelTypeSet& types_being_configured) const; // Start download of next set of types in |download_types_queue_| (if // any exist, does nothing otherwise). // Will kick off association of any new ready types. void StartNextDownload(syncer::ModelTypeSet high_priority_types_before); // Start association of next batch of data types after association of // previous batch finishes. |group| controls which set of types within // an AssociationTypesInfo to associate. Does nothing if model associator // is busy performing association. void StartNextAssociation(AssociationGroup group); void StopImpl(); BackendDataTypeConfigurer* configurer_; // Map of all data type controllers that are available for sync. // This list is determined at startup by various command line flags. const DataTypeController::TypeMap* controllers_; State state_; std::map start_order_; syncer::ModelTypeSet last_requested_types_; // Whether an attempt to reconfigure was made while we were busy configuring. // The |last_requested_types_| will reflect the newest set of requested types. bool needs_reconfigure_; // The reason for the last reconfigure attempt. Note: this will be set to a // valid value only when |needs_reconfigure_| is set. syncer::ConfigureReason last_configure_reason_; // The last time Restart() was called. base::Time last_restart_time_; // The accumulated time spent between calls to Restart() and going // to the DONE state. base::TimeDelta configure_time_delta_; // Sync's datatype debug info listener, which we pass model association // statistics to. const syncer::WeakHandle debug_info_listener_; // The manager that handles the model association of the individual types. ModelAssociationManager model_association_manager_; // DataTypeManager must have only one observer -- the ProfileSyncService that // created it and manages its lifetime. DataTypeManagerObserver* const observer_; // For querying failed data types (having unrecoverable error) when // configuring backend. DataTypeStatusTable data_type_status_table_; // Types waiting to be downloaded. TypeSetPriorityList download_types_queue_; // Types waiting for association and related time tracking info. struct AssociationTypesInfo { AssociationTypesInfo(); ~AssociationTypesInfo(); // Types to associate. syncer::ModelTypeSet types; // Types that have just been downloaded and are being associated for the // first time. This includes types that had previously encountered an error // and had to be purged/unapplied from the sync db. // This is a subset of |types|. syncer::ModelTypeSet first_sync_types; // Types that were already ready for association at configuration time. syncer::ModelTypeSet ready_types; // Time at which |types| began downloading. base::Time download_start_time; // Time at which |types| finished downloading. base::Time download_ready_time; // Time at which the association for |read_types| began. base::Time ready_association_request_time; // Time at which the association for |types| began (not relevant to // |ready_types|. base::Time full_association_request_time; // The set of types that are higher priority (and were therefore blocking) // the association of |types|. syncer::ModelTypeSet high_priority_types_before; // The subset of |types| that were successfully configured. syncer::ModelTypeSet configured_types; }; std::queue association_types_queue_; // The encryption handler lets the DataTypeManager know the state of sync // datatype encryption. const DataTypeEncryptionHandler* encryption_handler_; // Association and time stats of data type configuration. std::vector configuration_stats_; base::Closure unrecoverable_error_method_; // True iff we are in the process of catching up datatypes. bool catch_up_in_progress_; base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(DataTypeManagerImpl); }; } // namespace sync_driver #endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__