1 // Copyright (c) 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 CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 6 #define CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/callback_forward.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/synchronization/lock.h" 15 #include "base/synchronization/waitable_event.h" 16 #include "chrome/browser/sync/glue/data_type_controller.h" 17 #include "chrome/browser/sync/glue/data_type_error_handler.h" 18 #include "chrome/browser/sync/profile_sync_components_factory.h" 19 20 class Profile; 21 class ProfileSyncService; 22 class ProfileSyncComponentsFactory; 23 24 namespace base { 25 class TimeDelta; 26 } 27 28 namespace syncer { 29 class SyncError; 30 } 31 32 namespace browser_sync { 33 34 class AssociatorInterface; 35 class ChangeProcessor; 36 37 // Implementation for datatypes that do not reside on the frontend thread 38 // (UI thread). This is the same thread we perform initialization 39 // on, so we don't have to worry about thread safety. The main start/stop 40 // functionality is implemented by default. Derived classes must implement: 41 // type() 42 // model_safe_group() 43 // PostTaskOnBackendThread() 44 // CreateSyncComponents() 45 class NonFrontendDataTypeController : public DataTypeController { 46 public: 47 // For creating non-frontend processor/associator and associating on backend. 48 class BackendComponentsContainer; 49 50 NonFrontendDataTypeController( 51 ProfileSyncComponentsFactory* profile_sync_factory, 52 Profile* profile, 53 ProfileSyncService* sync_service); 54 55 // DataTypeController interface. 56 virtual void LoadModels( 57 const ModelLoadCallback& model_load_callback) OVERRIDE; 58 virtual void StartAssociating(const StartCallback& start_callback) OVERRIDE; 59 virtual void Stop() OVERRIDE; 60 virtual syncer::ModelType type() const = 0; 61 virtual syncer::ModelSafeGroup model_safe_group() const = 0; 62 virtual std::string name() const OVERRIDE; 63 virtual State state() const OVERRIDE; 64 65 // DataTypeErrorHandler interface. 66 // Note: this is performed on the datatype's thread. 67 virtual void OnSingleDatatypeUnrecoverableError( 68 const tracked_objects::Location& from_here, 69 const std::string& message) OVERRIDE; 70 71 // Callback to receive background association results. 72 struct AssociationResult { 73 explicit AssociationResult(syncer::ModelType type); 74 ~AssociationResult(); 75 bool needs_crypto; 76 bool unrecoverable_error; 77 bool sync_has_nodes; 78 syncer::SyncError error; 79 syncer::SyncMergeResult local_merge_result; 80 syncer::SyncMergeResult syncer_merge_result; 81 base::TimeDelta association_time; 82 ChangeProcessor* change_processor; 83 AssociatorInterface* model_associator; 84 }; 85 void AssociationCallback(AssociationResult result); 86 87 protected: 88 // For testing only. 89 NonFrontendDataTypeController(); 90 91 virtual ~NonFrontendDataTypeController(); 92 93 // DataTypeController interface. 94 virtual void OnModelLoaded() OVERRIDE; 95 96 // Start any dependent services that need to be running before we can 97 // associate models. The default implementation is a no-op. 98 // Return value: 99 // True - if models are ready and association can proceed. 100 // False - if models are not ready. StartAssociationAsync should be called 101 // when the models are ready. 102 // Note: this is performed on the frontend (UI) thread. 103 virtual bool StartModels(); 104 105 // Posts the given task to the backend thread, i.e. the thread the 106 // datatype lives on. Return value: True if task posted successfully, 107 // false otherwise. 108 // NOTE: The StopAssociationAsync() implementation relies on the fact that 109 // implementations of this API do not hold any references to the DTC while 110 // the task is executing. See http://crbug.com/127706. 111 virtual bool PostTaskOnBackendThread( 112 const tracked_objects::Location& from_here, 113 const base::Closure& task) = 0; 114 115 // Datatype specific creation of sync components. 116 // Note: this is performed on the datatype's thread. 117 virtual ProfileSyncComponentsFactory::SyncComponents 118 CreateSyncComponents() = 0; 119 120 // Called on UI thread during shutdown to effectively disable processing 121 // any changes. 122 virtual void DisconnectProcessor(ChangeProcessor* processor) = 0; 123 124 // Start up complete, update the state and invoke the callback. 125 // Note: this is performed on the datatype's thread. 126 virtual void StartDone( 127 DataTypeController::StartResult start_result, 128 const syncer::SyncMergeResult& local_merge_result, 129 const syncer::SyncMergeResult& syncer_merge_result); 130 131 // UI thread implementation of StartDone. 132 virtual void StartDoneImpl( 133 DataTypeController::StartResult start_result, 134 DataTypeController::State new_state, 135 const syncer::SyncMergeResult& local_merge_result, 136 const syncer::SyncMergeResult& syncer_merge_result); 137 138 // The actual implementation of Disabling the datatype. This happens 139 // on the UI thread. 140 virtual void DisableImpl(const tracked_objects::Location& from_here, 141 const std::string& message); 142 143 // Record association time. Called on Datatype's thread. 144 virtual void RecordAssociationTime(base::TimeDelta time); 145 // Record causes of start failure. Called on UI thread. 146 virtual void RecordStartFailure(StartResult result); 147 148 // Accessors and mutators used by derived classes. 149 ProfileSyncComponentsFactory* profile_sync_factory() const; 150 Profile* profile() const; 151 ProfileSyncService* profile_sync_service() const; 152 void set_start_callback(const StartCallback& callback); 153 void set_state(State state); 154 155 virtual AssociatorInterface* associator() const; 156 virtual ChangeProcessor* change_processor() const; 157 158 State state_; 159 StartCallback start_callback_; 160 ModelLoadCallback model_load_callback_; 161 162 private: 163 friend class BackendComponentsContainer; 164 ProfileSyncComponentsFactory* const profile_sync_factory_; 165 Profile* const profile_; 166 ProfileSyncService* const profile_sync_service_; 167 168 // Created on UI thread and passed to backend to create processor/associator 169 // and associate model. Released on backend. 170 scoped_ptr<BackendComponentsContainer> components_container_; 171 172 AssociatorInterface* model_associator_; 173 ChangeProcessor* change_processor_; 174 175 base::WeakPtrFactory<NonFrontendDataTypeController> weak_ptr_factory_; 176 177 DISALLOW_COPY_AND_ASSIGN(NonFrontendDataTypeController); 178 }; 179 180 } // namespace browser_sync 181 182 #endif // CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__ 183