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.
5 #ifndef CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__
6 #define CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__
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"
21 class ProfileSyncService;
22 class ProfileSyncComponentsFactory;
32 namespace browser_sync {
34 class AssociatorInterface;
35 class ChangeProcessor;
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:
43 // PostTaskOnBackendThread()
44 // CreateSyncComponents()
45 class NonFrontendDataTypeController : public DataTypeController {
47 // For creating non-frontend processor/associator and associating on backend.
48 class BackendComponentsContainer;
50 NonFrontendDataTypeController(
51 scoped_refptr<base::MessageLoopProxy> ui_thread,
52 const base::Closure& error_callback,
53 ProfileSyncComponentsFactory* profile_sync_factory,
55 ProfileSyncService* sync_service);
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;
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;
73 // Callback to receive background association results.
74 struct AssociationResult {
75 explicit AssociationResult(syncer::ModelType type);
78 bool unrecoverable_error;
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;
87 void AssociationCallback(AssociationResult result);
91 NonFrontendDataTypeController();
93 virtual ~NonFrontendDataTypeController();
95 // DataTypeController interface.
96 virtual void OnModelLoaded() OVERRIDE;
98 // Start any dependent services that need to be running before we can
99 // associate models. The default implementation is a no-op.
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();
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,
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;
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();
123 // Datatype specific creation of sync components.
124 // Note: this is performed on the datatype's thread.
125 virtual ProfileSyncComponentsFactory::SyncComponents
126 CreateSyncComponents() = 0;
128 // Called on UI thread during shutdown to effectively disable processing
130 virtual void DisconnectProcessor(ChangeProcessor* processor) = 0;
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);
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);
146 // The actual implementation of Disabling the datatype. This happens
148 virtual void DisableImpl(const tracked_objects::Location& from_here,
149 const std::string& message);
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);
156 // Accessors and mutators used by derived classes.
157 ProfileSyncComponentsFactory* profile_sync_factory() const;
158 Profile* profile() const;
159 ProfileSyncService* profile_sync_service() const;
160 void set_start_callback(const StartCallback& callback);
161 void set_state(State state);
163 virtual AssociatorInterface* associator() const;
164 virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
167 StartCallback start_callback_;
168 ModelLoadCallback model_load_callback_;
171 friend class BackendComponentsContainer;
172 ProfileSyncComponentsFactory* const profile_sync_factory_;
173 Profile* const profile_;
174 ProfileSyncService* const profile_sync_service_;
176 // Created on UI thread and passed to backend to create processor/associator
177 // and associate model. Released on backend.
178 scoped_ptr<BackendComponentsContainer> components_container_;
180 AssociatorInterface* model_associator_;
181 ChangeProcessor* change_processor_;
183 base::WeakPtrFactory<NonFrontendDataTypeController> weak_ptr_factory_;
185 DISALLOW_COPY_AND_ASSIGN(NonFrontendDataTypeController);
188 } // namespace browser_sync
190 #endif // CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__