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" 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_components_factory.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/data_type_controller.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/data_type_error_handler.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) 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace sync_driver { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AssociatorInterface; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChangeProcessor; 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace browser_sync { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation for datatypes that do not reside on the frontend thread 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (UI thread). This is the same thread we perform initialization 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on, so we don't have to worry about thread safety. The main start/stop 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// functionality is implemented by default. Derived classes must implement: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type() 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// model_safe_group() 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PostTaskOnBackendThread() 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CreateSyncComponents() 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class NonFrontendDataTypeController : public sync_driver::DataTypeController { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // For creating non-frontend processor/associator and associating on backend. 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) class BackendComponentsContainer; 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonFrontendDataTypeController( 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> ui_thread, 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& error_callback, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* profile_sync_factory, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* sync_service); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DataTypeController interface. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadModels( 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelLoadCallback& model_load_callback) OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StartAssociating(const StartCallback& start_callback) OVERRIDE; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Stop() OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelType type() const = 0; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelSafeGroup model_safe_group() const = 0; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string name() const OVERRIDE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual State state() const OVERRIDE; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DataTypeErrorHandler interface. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the datatype's thread. 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void OnSingleDataTypeUnrecoverableError( 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const syncer::SyncError& error) OVERRIDE; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Callback to receive background association results. 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct AssociationResult { 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) explicit AssociationResult(syncer::ModelType type); 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ~AssociationResult(); 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool needs_crypto; 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool unrecoverable_error; 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool sync_has_nodes; 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::SyncError error; 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::SyncMergeResult local_merge_result; 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::SyncMergeResult syncer_merge_result; 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta association_time; 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::ChangeProcessor* change_processor; 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::AssociatorInterface* model_associator; 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void AssociationCallback(AssociationResult result); 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing only. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonFrontendDataTypeController(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~NonFrontendDataTypeController(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DataTypeController interface. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnModelLoaded() OVERRIDE; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start any dependent services that need to be running before we can 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associate models. The default implementation is a no-op. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return value: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True - if models are ready and association can proceed. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // False - if models are not ready. StartAssociationAsync should be called 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when the models are ready. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the frontend (UI) thread. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool StartModels(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Posts the given task to the backend thread, i.e. the thread the 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // datatype lives on. Return value: True if task posted successfully, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false otherwise. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: The StopAssociationAsync() implementation relies on the fact that 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // implementations of this API do not hold any references to the DTC while 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the task is executing. See http://crbug.com/127706. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool PostTaskOnBackendThread( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) = 0; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns true if the current thread is the backend thread, i.e. the same 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // thread used by |PostTaskOnBackendThread|. The default implementation just 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // checks that the current thread is not the UI thread, but subclasses should 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // override it appropriately. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool IsOnBackendThread(); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Datatype specific creation of sync components. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the datatype's thread. 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual ProfileSyncComponentsFactory::SyncComponents 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CreateSyncComponents() = 0; 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Called on UI thread during shutdown to effectively disable processing 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // any changes. 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void DisconnectProcessor(sync_driver::ChangeProcessor* processor) = 0; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start up complete, update the state and invoke the callback. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this is performed on the datatype's thread. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void StartDone( 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DataTypeController::ConfigureResult start_result, 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UI thread implementation of StartDone. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void StartDoneImpl( 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DataTypeController::ConfigureResult start_result, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DataTypeController::State new_state, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual implementation of Disabling the datatype. This happens 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the UI thread. 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void DisableImpl(const syncer::SyncError& error); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record association time. Called on Datatype's thread. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordAssociationTime(base::TimeDelta time); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record causes of start failure. Called on UI thread. 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void RecordStartFailure(ConfigureResult result); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Handles the reporting of unrecoverable error. It records stuff in 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // UMA and reports to breakpad. 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Virtual for testing purpose. 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void RecordUnrecoverableError( 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const tracked_objects::Location& from_here, 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& message); 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accessors and mutators used by derived classes. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* profile_sync_factory() const; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile() const; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* profile_sync_service() const; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_start_callback(const StartCallback& callback); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_state(State state); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual sync_driver::AssociatorInterface* associator() const; 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual sync_driver::ChangeProcessor* GetChangeProcessor() const OVERRIDE; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartCallback start_callback_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelLoadCallback model_load_callback_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) friend class BackendComponentsContainer; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* const profile_sync_factory_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* const profile_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* const profile_sync_service_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Created on UI thread and passed to backend to create processor/associator 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // and associate model. Released on backend. 185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<BackendComponentsContainer> components_container_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::AssociatorInterface* model_associator_; 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::ChangeProcessor* change_processor_; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtrFactory<NonFrontendDataTypeController> weak_ptr_factory_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NonFrontendDataTypeController); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 198