Home | History | Annotate | Download | only in sync_driver
      1 // Copyright 2014 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
      6 #define COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/callback.h"
     12 #include "base/location.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/ref_counted_delete_on_message_loop.h"
     15 #include "base/sequenced_task_runner_helpers.h"
     16 #include "components/sync_driver/data_type_error_handler.h"
     17 #include "sync/api/sync_merge_result.h"
     18 #include "sync/internal_api/public/base/model_type.h"
     19 #include "sync/internal_api/public/engine/model_safe_worker.h"
     20 #include "sync/internal_api/public/util/unrecoverable_error_handler.h"
     21 
     22 namespace syncer {
     23 class SyncError;
     24 struct UserShare;
     25 }
     26 
     27 namespace sync_driver {
     28 
     29 class ChangeProcessor;
     30 
     31 // Data type controllers need to be refcounted threadsafe, as they may
     32 // need to run model associator or change processor on other threads.
     33 class DataTypeController
     34     : public base::RefCountedDeleteOnMessageLoop<DataTypeController>,
     35       public DataTypeErrorHandler {
     36  public:
     37   enum State {
     38     NOT_RUNNING,    // The controller has never been started or has
     39                     // previously been stopped.  Must be in this state to start.
     40     MODEL_STARTING, // The controller is waiting on dependent services
     41                     // that need to be available before model
     42                     // association.
     43     MODEL_LOADED,   // The model has finished loading and can start
     44                     // associating now.
     45     ASSOCIATING,    // Model association is in progress.
     46     RUNNING,        // The controller is running and the data type is
     47                     // in sync with the cloud.
     48     STOPPING,       // The controller is in the process of stopping
     49                     // and is waiting for dependent services to stop.
     50     DISABLED        // The controller was started but encountered an error
     51                     // so it is disabled waiting for it to be stopped.
     52   };
     53 
     54   enum ConfigureResult {
     55     OK,                   // The data type has started normally.
     56     OK_FIRST_RUN,         // Same as OK, but sent on first successful
     57                           // start for this type for this user as
     58                           // determined by cloud state.
     59     ASSOCIATION_FAILED,   // An error occurred during model association.
     60     ABORTED,              // Start was aborted by calling Stop().
     61     UNRECOVERABLE_ERROR,  // An unrecoverable error occured.
     62     NEEDS_CRYPTO,         // The data type cannot be started yet because it
     63                           // depends on the cryptographer.
     64     RUNTIME_ERROR,        // After starting, a runtime error was encountered.
     65     MAX_START_RESULT
     66   };
     67 
     68   typedef base::Callback<void(ConfigureResult,
     69                               const syncer::SyncMergeResult&,
     70                               const syncer::SyncMergeResult&)> StartCallback;
     71 
     72   typedef base::Callback<void(syncer::ModelType,
     73                               syncer::SyncError)> ModelLoadCallback;
     74 
     75   typedef base::Callback<void(const tracked_objects::Location& location,
     76                               const std::string&)> DisableTypeCallback;
     77 
     78   typedef std::map<syncer::ModelType,
     79                    scoped_refptr<DataTypeController> > TypeMap;
     80   typedef std::map<syncer::ModelType, DataTypeController::State> StateMap;
     81 
     82   // Returns true if the start result should trigger an unrecoverable error.
     83   // Public so unit tests can use this function as well.
     84   static bool IsUnrecoverableResult(ConfigureResult result);
     85 
     86   // Returns true if the datatype started successfully.
     87   static bool IsSuccessfulResult(ConfigureResult result);
     88 
     89   // Begins asynchronous operation of loading the model to get it ready for
     90   // model association. Once the models are loaded the callback will be invoked
     91   // with the result. If the models are already loaded it is safe to call the
     92   // callback right away. Else the callback needs to be stored and called when
     93   // the models are ready.
     94   virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0;
     95 
     96   // Will start a potentially asynchronous operation to perform the
     97   // model association. Once the model association is done the callback will
     98   // be invoked.
     99   virtual void StartAssociating(const StartCallback& start_callback) = 0;
    100 
    101   // Synchronously stops the data type. If StartAssociating has already been
    102   // called but is not done yet it will be aborted. Similarly if LoadModels
    103   // has not completed it will also be aborted.
    104   // NOTE: Stop() should be called after sync backend machinery has stopped
    105   // routing changes to this data type. Stop() should ensure the data type
    106   // logic shuts down gracefully by flushing remaining changes and calling
    107   // StopSyncing on the SyncableService. This assumes no changes will ever
    108   // propagate from sync again from point where Stop() is called.
    109   virtual void Stop() = 0;
    110 
    111   // Unique model type for this data type controller.
    112   virtual syncer::ModelType type() const = 0;
    113 
    114   // Name of this data type.  For logging purposes only.
    115   virtual std::string name() const = 0;
    116 
    117   // The model safe group of this data type.  This should reflect the
    118   // thread that should be used to modify the data type's native
    119   // model.
    120   virtual syncer::ModelSafeGroup model_safe_group() const = 0;
    121 
    122   // Access to the ChangeProcessor for the type being controlled by |this|.
    123   // Returns NULL if the ChangeProcessor isn't created or connected.
    124   virtual ChangeProcessor* GetChangeProcessor() const = 0;
    125 
    126   // Current state of the data type controller.
    127   virtual State state() const = 0;
    128 
    129   // Partial implementation of DataTypeErrorHandler.
    130   // This is thread safe.
    131   virtual syncer::SyncError CreateAndUploadError(
    132       const tracked_objects::Location& location,
    133       const std::string& message,
    134       syncer::ModelType type) OVERRIDE;
    135 
    136   // Called when the sync backend has initialized. |share| is the
    137   // UserShare handle to associate model data with.
    138   void OnUserShareReady(syncer::UserShare* share);
    139 
    140   // Whether the DataTypeController is ready to start. This is useful if the
    141   // datatype itself must make the decision about whether it should be enabled
    142   // at all (and therefore whether the initial download of the sync data for
    143   // the type should be performed).
    144   // Returns true by default.
    145   virtual bool ReadyForStart() const;
    146 
    147  protected:
    148   friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>;
    149   friend class base::DeleteHelper<DataTypeController>;
    150 
    151   DataTypeController(scoped_refptr<base::MessageLoopProxy> ui_thread,
    152                      const base::Closure& error_callback);
    153 
    154   // If the DTC is waiting for models to load, once the models are
    155   // loaded the datatype service will call this function on DTC to let
    156   // us know that it is safe to start associating.
    157   virtual void OnModelLoaded() = 0;
    158 
    159   virtual ~DataTypeController();
    160 
    161   syncer::UserShare* user_share() const;
    162 
    163   // The callback that will be invoked when an unrecoverable error occurs.
    164   // TODO(sync): protected for use by legacy controllers.
    165   base::Closure error_callback_;
    166 
    167  private:
    168   syncer::UserShare* user_share_;
    169 };
    170 
    171 }  // namespace sync_driver
    172 
    173 #endif  // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
    174