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 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 scoped_refptr<base::MessageLoopProxy> ui_thread, 52 const base::Closure& error_callback, 53 ProfileSyncComponentsFactory* profile_sync_factory, 54 Profile* profile, 55 ProfileSyncService* sync_service); 56 57 // DataTypeController interface. 58 virtual void LoadModels( 59 const ModelLoadCallback& model_load_callback) OVERRIDE; 60 virtual void StartAssociating(const StartCallback& start_callback) OVERRIDE; 61 virtual void Stop() OVERRIDE; 62 virtual syncer::ModelType type() const = 0; 63 virtual syncer::ModelSafeGroup model_safe_group() const = 0; 64 virtual std::string name() const OVERRIDE; 65 virtual State state() const OVERRIDE; 66 67 // DataTypeErrorHandler interface. 68 // Note: this is performed on the datatype's thread. 69 virtual void OnSingleDatatypeUnrecoverableError( 70 const tracked_objects::Location& from_here, 71 const std::string& message) OVERRIDE; 72 73 // Callback to receive background association results. 74 struct AssociationResult { 75 explicit AssociationResult(syncer::ModelType type); 76 ~AssociationResult(); 77 bool needs_crypto; 78 bool unrecoverable_error; 79 bool sync_has_nodes; 80 syncer::SyncError error; 81 syncer::SyncMergeResult local_merge_result; 82 syncer::SyncMergeResult syncer_merge_result; 83 base::TimeDelta association_time; 84 ChangeProcessor* change_processor; 85 AssociatorInterface* model_associator; 86 }; 87 void AssociationCallback(AssociationResult result); 88 89 protected: 90 // For testing only. 91 NonFrontendDataTypeController(); 92 93 virtual ~NonFrontendDataTypeController(); 94 95 // DataTypeController interface. 96 virtual void OnModelLoaded() OVERRIDE; 97 98 // Start any dependent services that need to be running before we can 99 // associate models. The default implementation is a no-op. 100 // Return value: 101 // True - if models are ready and association can proceed. 102 // False - if models are not ready. StartAssociationAsync should be called 103 // when the models are ready. 104 // Note: this is performed on the frontend (UI) thread. 105 virtual bool StartModels(); 106 107 // Posts the given task to the backend thread, i.e. the thread the 108 // datatype lives on. Return value: True if task posted successfully, 109 // false otherwise. 110 // NOTE: The StopAssociationAsync() implementation relies on the fact that 111 // implementations of this API do not hold any references to the DTC while 112 // the task is executing. See http://crbug.com/127706. 113 virtual bool PostTaskOnBackendThread( 114 const tracked_objects::Location& from_here, 115 const base::Closure& task) = 0; 116 117 // Returns true if the current thread is the backend thread, i.e. the same 118 // thread used by |PostTaskOnBackendThread|. The default implementation just 119 // checks that the current thread is not the UI thread, but subclasses should 120 // override it appropriately. 121 virtual bool IsOnBackendThread(); 122 123 // Datatype specific creation of sync components. 124 // Note: this is performed on the datatype's thread. 125 virtual ProfileSyncComponentsFactory::SyncComponents 126 CreateSyncComponents() = 0; 127 128 // Called on UI thread during shutdown to effectively disable processing 129 // any changes. 130 virtual void DisconnectProcessor(ChangeProcessor* processor) = 0; 131 132 // Start up complete, update the state and invoke the callback. 133 // Note: this is performed on the datatype's thread. 134 virtual void StartDone( 135 DataTypeController::StartResult start_result, 136 const syncer::SyncMergeResult& local_merge_result, 137 const syncer::SyncMergeResult& syncer_merge_result); 138 139 // UI thread implementation of StartDone. 140 virtual void StartDoneImpl( 141 DataTypeController::StartResult start_result, 142 DataTypeController::State new_state, 143 const syncer::SyncMergeResult& local_merge_result, 144 const syncer::SyncMergeResult& syncer_merge_result); 145 146 // The actual implementation of Disabling the datatype. This happens 147 // on the UI thread. 148 virtual void DisableImpl(const tracked_objects::Location& from_here, 149 const std::string& message); 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(StartResult 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 AssociatorInterface* associator() const; 171 virtual 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 AssociatorInterface* model_associator_; 188 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