15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/data_type_controller.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/data_type_error_handler.h" 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_components_factory.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProfileSyncService; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProfileSyncComponentsFactory; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeDelta; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncError; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AssociatorInterface; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChangeProcessor; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation for datatypes that do not reside on the frontend thread 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (UI thread). This is the same thread we perform initialization 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on, so we don't have to worry about thread safety. The main start/stop 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// functionality is implemented by default. Derived classes must implement: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type() 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// model_safe_group() 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PostTaskOnBackendThread() 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CreateSyncComponents() 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NonFrontendDataTypeController : public DataTypeController { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // For creating non-frontend processor/associator and associating on backend. 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) class BackendComponentsContainer; 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonFrontendDataTypeController( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* profile_sync_factory, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* sync_service); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DataTypeController interface. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadModels( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelLoadCallback& model_load_callback) OVERRIDE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StartAssociating(const StartCallback& start_callback) OVERRIDE; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Stop() OVERRIDE; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelType type() const = 0; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelSafeGroup model_safe_group() const = 0; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string name() const OVERRIDE; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual State state() const OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DataTypeErrorHandler interface. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the datatype's thread. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnSingleDatatypeUnrecoverableError( 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message) OVERRIDE; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Callback to receive background association results. 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct AssociationResult { 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) explicit AssociationResult(syncer::ModelType type); 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ~AssociationResult(); 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool needs_crypto; 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool unrecoverable_error; 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool sync_has_nodes; 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::SyncError error; 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::SyncMergeResult local_merge_result; 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::SyncMergeResult syncer_merge_result; 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta association_time; 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ChangeProcessor* change_processor; 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AssociatorInterface* model_associator; 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void AssociationCallback(AssociationResult result); 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing only. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonFrontendDataTypeController(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~NonFrontendDataTypeController(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DataTypeController interface. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnModelLoaded() OVERRIDE; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start any dependent services that need to be running before we can 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associate models. The default implementation is a no-op. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return value: 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True - if models are ready and association can proceed. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // False - if models are not ready. StartAssociationAsync should be called 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when the models are ready. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the frontend (UI) thread. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool StartModels(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Posts the given task to the backend thread, i.e. the thread the 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // datatype lives on. Return value: True if task posted successfully, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false otherwise. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: The StopAssociationAsync() implementation relies on the fact that 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // implementations of this API do not hold any references to the DTC while 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the task is executing. See http://crbug.com/127706. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool PostTaskOnBackendThread( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) = 0; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Datatype specific creation of sync components. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the datatype's thread. 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual ProfileSyncComponentsFactory::SyncComponents 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateSyncComponents() = 0; 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Called on UI thread during shutdown to effectively disable processing 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // any changes. 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void DisconnectProcessor(ChangeProcessor* processor) = 0; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start up complete, update the state and invoke the callback. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the datatype's thread. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void StartDone( 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DataTypeController::StartResult start_result, 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UI thread implementation of StartDone. 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void StartDoneImpl( 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DataTypeController::StartResult start_result, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DataTypeController::State new_state, 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual implementation of Disabling the datatype. This happens 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the UI thread. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DisableImpl(const tracked_objects::Location& from_here, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record association time. Called on Datatype's thread. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordAssociationTime(base::TimeDelta time); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record causes of start failure. Called on UI thread. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordStartFailure(StartResult result); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accessors and mutators used by derived classes. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* profile_sync_factory() const; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile() const; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* profile_sync_service() const; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_start_callback(const StartCallback& callback); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_state(State state); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual AssociatorInterface* associator() const; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ChangeProcessor* change_processor() const; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state_; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartCallback start_callback_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelLoadCallback model_load_callback_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) friend class BackendComponentsContainer; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* const profile_sync_factory_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* const profile_; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* const profile_sync_service_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Created on UI thread and passed to backend to create processor/associator 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // and associate model. Released on backend. 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<BackendComponentsContainer> components_container_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AssociatorInterface* model_associator_; 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ChangeProcessor* change_processor_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtrFactory<NonFrontendDataTypeController> weak_ptr_factory_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NonFrontendDataTypeController); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 183