Home | History | Annotate | Download | only in glue
      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