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/glue/data_type_controller.h"
     17 #include "chrome/browser/sync/glue/data_type_error_handler.h"
     18 #include "chrome/browser/sync/profile_sync_components_factory.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       ProfileSyncComponentsFactory* profile_sync_factory,
     52       Profile* profile,
     53       ProfileSyncService* sync_service);
     54 
     55   // DataTypeController interface.
     56   virtual void LoadModels(
     57       const ModelLoadCallback& model_load_callback) OVERRIDE;
     58   virtual void StartAssociating(const StartCallback& start_callback) OVERRIDE;
     59   virtual void Stop() OVERRIDE;
     60   virtual syncer::ModelType type() const = 0;
     61   virtual syncer::ModelSafeGroup model_safe_group() const = 0;
     62   virtual std::string name() const OVERRIDE;
     63   virtual State state() const OVERRIDE;
     64 
     65   // DataTypeErrorHandler interface.
     66   // Note: this is performed on the datatype's thread.
     67   virtual void OnSingleDatatypeUnrecoverableError(
     68       const tracked_objects::Location& from_here,
     69       const std::string& message) OVERRIDE;
     70 
     71   // Callback to receive background association results.
     72   struct AssociationResult {
     73     explicit AssociationResult(syncer::ModelType type);
     74     ~AssociationResult();
     75     bool needs_crypto;
     76     bool unrecoverable_error;
     77     bool sync_has_nodes;
     78     syncer::SyncError error;
     79     syncer::SyncMergeResult local_merge_result;
     80     syncer::SyncMergeResult syncer_merge_result;
     81     base::TimeDelta association_time;
     82     ChangeProcessor* change_processor;
     83     AssociatorInterface* model_associator;
     84   };
     85   void AssociationCallback(AssociationResult result);
     86 
     87  protected:
     88   // For testing only.
     89   NonFrontendDataTypeController();
     90 
     91   virtual ~NonFrontendDataTypeController();
     92 
     93   // DataTypeController interface.
     94   virtual void OnModelLoaded() OVERRIDE;
     95 
     96   // Start any dependent services that need to be running before we can
     97   // associate models. The default implementation is a no-op.
     98   // Return value:
     99   //   True - if models are ready and association can proceed.
    100   //   False - if models are not ready. StartAssociationAsync should be called
    101   //           when the models are ready.
    102   // Note: this is performed on the frontend (UI) thread.
    103   virtual bool StartModels();
    104 
    105   // Posts the given task to the backend thread, i.e. the thread the
    106   // datatype lives on.  Return value: True if task posted successfully,
    107   // false otherwise.
    108   // NOTE: The StopAssociationAsync() implementation relies on the fact that
    109   // implementations of this API do not hold any references to the DTC while
    110   // the task is executing. See http://crbug.com/127706.
    111   virtual bool PostTaskOnBackendThread(
    112       const tracked_objects::Location& from_here,
    113       const base::Closure& task) = 0;
    114 
    115   // Datatype specific creation of sync components.
    116   // Note: this is performed on the datatype's thread.
    117   virtual ProfileSyncComponentsFactory::SyncComponents
    118       CreateSyncComponents() = 0;
    119 
    120   // Called on UI thread during shutdown to effectively disable processing
    121   // any changes.
    122   virtual void DisconnectProcessor(ChangeProcessor* processor) = 0;
    123 
    124   // Start up complete, update the state and invoke the callback.
    125   // Note: this is performed on the datatype's thread.
    126   virtual void StartDone(
    127       DataTypeController::StartResult start_result,
    128       const syncer::SyncMergeResult& local_merge_result,
    129       const syncer::SyncMergeResult& syncer_merge_result);
    130 
    131   // UI thread implementation of StartDone.
    132   virtual void StartDoneImpl(
    133       DataTypeController::StartResult start_result,
    134       DataTypeController::State new_state,
    135       const syncer::SyncMergeResult& local_merge_result,
    136       const syncer::SyncMergeResult& syncer_merge_result);
    137 
    138   // The actual implementation of Disabling the datatype. This happens
    139   // on the UI thread.
    140   virtual void DisableImpl(const tracked_objects::Location& from_here,
    141                            const std::string& message);
    142 
    143   // Record association time. Called on Datatype's thread.
    144   virtual void RecordAssociationTime(base::TimeDelta time);
    145   // Record causes of start failure. Called on UI thread.
    146   virtual void RecordStartFailure(StartResult result);
    147 
    148   // Accessors and mutators used by derived classes.
    149   ProfileSyncComponentsFactory* profile_sync_factory() const;
    150   Profile* profile() const;
    151   ProfileSyncService* profile_sync_service() const;
    152   void set_start_callback(const StartCallback& callback);
    153   void set_state(State state);
    154 
    155   virtual AssociatorInterface* associator() const;
    156   virtual ChangeProcessor* change_processor() const;
    157 
    158   State state_;
    159   StartCallback start_callback_;
    160   ModelLoadCallback model_load_callback_;
    161 
    162  private:
    163   friend class BackendComponentsContainer;
    164   ProfileSyncComponentsFactory* const profile_sync_factory_;
    165   Profile* const profile_;
    166   ProfileSyncService* const profile_sync_service_;
    167 
    168   // Created on UI thread and passed to backend to create processor/associator
    169   // and associate model. Released on backend.
    170   scoped_ptr<BackendComponentsContainer> components_container_;
    171 
    172   AssociatorInterface* model_associator_;
    173   ChangeProcessor* change_processor_;
    174 
    175   base::WeakPtrFactory<NonFrontendDataTypeController> weak_ptr_factory_;
    176 
    177   DISALLOW_COPY_AND_ASSIGN(NonFrontendDataTypeController);
    178 };
    179 
    180 }  // namespace browser_sync
    181 
    182 #endif  // CHROME_BROWSER_SYNC_GLUE_NON_FRONTEND_DATA_TYPE_CONTROLLER_H__
    183