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