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 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