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_DATA_TYPE_CONTROLLER_H__
      6 #define CHROME_BROWSER_SYNC_GLUE_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/sequenced_task_runner_helpers.h"
     14 #include "chrome/browser/sync/glue/data_type_error_handler.h"
     15 #include "content/public/browser/browser_thread.h"
     16 #include "sync/api/sync_merge_result.h"
     17 #include "sync/internal_api/public/base/model_type.h"
     18 #include "sync/internal_api/public/engine/model_safe_worker.h"
     19 #include "sync/internal_api/public/util/unrecoverable_error_handler.h"
     20 
     21 namespace syncer {
     22 class SyncError;
     23 }
     24 
     25 namespace browser_sync {
     26 
     27 // Data type controllers need to be refcounted threadsafe, as they may
     28 // need to run model associator or change processor on other threads.
     29 class DataTypeController
     30     : public base::RefCountedThreadSafe<
     31           DataTypeController, content::BrowserThread::DeleteOnUIThread>,
     32       public DataTypeErrorHandler {
     33  public:
     34   enum State {
     35     NOT_RUNNING,    // The controller has never been started or has
     36                     // previously been stopped.  Must be in this state to start.
     37     MODEL_STARTING, // The controller is waiting on dependent services
     38                     // that need to be available before model
     39                     // association.
     40     MODEL_LOADED,   // The model has finished loading and can start
     41                     // associating now.
     42     ASSOCIATING,    // Model association is in progress.
     43     RUNNING,        // The controller is running and the data type is
     44                     // in sync with the cloud.
     45     STOPPING,       // The controller is in the process of stopping
     46                     // and is waiting for dependent services to stop.
     47     DISABLED        // The controller was started but encountered an error
     48                     // so it is disabled waiting for it to be stopped.
     49   };
     50 
     51   enum StartResult {
     52     OK,                   // The data type has started normally.
     53     OK_FIRST_RUN,         // Same as OK, but sent on first successful
     54                           // start for this type for this user as
     55                           // determined by cloud state.
     56     BUSY,                 // Start() was called while already in progress.
     57     NOT_ENABLED,          // This data type is not enabled for the current user.
     58     ASSOCIATION_FAILED,   // An error occurred during model association.
     59     ABORTED,              // Start was aborted by calling Stop().
     60     UNRECOVERABLE_ERROR,  // An unrecoverable error occured.
     61     NEEDS_CRYPTO,         // The data type cannot be started yet because it
     62                           // depends on the cryptographer.
     63     MAX_START_RESULT
     64   };
     65 
     66   typedef base::Callback<void(StartResult,
     67                               const syncer::SyncMergeResult&,
     68                               const syncer::SyncMergeResult&)> StartCallback;
     69 
     70   typedef base::Callback<void(syncer::ModelType,
     71                               syncer::SyncError)> ModelLoadCallback;
     72 
     73   typedef std::map<syncer::ModelType,
     74                    scoped_refptr<DataTypeController> > TypeMap;
     75   typedef std::map<syncer::ModelType, DataTypeController::State> StateMap;
     76 
     77   // Returns true if the start result should trigger an unrecoverable error.
     78   // Public so unit tests can use this function as well.
     79   static bool IsUnrecoverableResult(StartResult result);
     80 
     81   // Returns true if the datatype started successfully.
     82   static bool IsSuccessfulResult(StartResult result);
     83 
     84   // Begins asynchronous operation of loading the model to get it ready for
     85   // model association. Once the models are loaded the callback will be invoked
     86   // with the result. If the models are already loaded it is safe to call the
     87   // callback right away. Else the callback needs to be stored and called when
     88   // the models are ready.
     89   virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0;
     90 
     91   // Will start a potentially asynchronous operation to perform the
     92   // model association. Once the model association is done the callback will
     93   // be invoked.
     94   virtual void StartAssociating(const StartCallback& start_callback) = 0;
     95 
     96   // Synchronously stops the data type. If StartAssociating has already been
     97   // called but is not done yet it will be aborted. Similarly if LoadModels
     98   // has not completed it will also be aborted.
     99   virtual void Stop() = 0;
    100 
    101   // Unique model type for this data type controller.
    102   virtual syncer::ModelType type() const = 0;
    103 
    104   // Name of this data type.  For logging purposes only.
    105   virtual std::string name() const = 0;
    106 
    107   // The model safe group of this data type.  This should reflect the
    108   // thread that should be used to modify the data type's native
    109   // model.
    110   virtual syncer::ModelSafeGroup model_safe_group() const = 0;
    111 
    112   // Current state of the data type controller.
    113   virtual State state() const = 0;
    114 
    115   // Partial implementation of DataTypeErrorHandler.
    116   // This is thread safe.
    117   virtual syncer::SyncError CreateAndUploadError(
    118       const tracked_objects::Location& location,
    119       const std::string& message,
    120       syncer::ModelType type) OVERRIDE;
    121 
    122  protected:
    123   friend struct content::BrowserThread::DeleteOnThread<
    124       content::BrowserThread::UI>;
    125   friend class base::DeleteHelper<DataTypeController>;
    126 
    127   // If the DTC is waiting for models to load, once the models are
    128   // loaded the datatype service will call this function on DTC to let
    129   // us know that it is safe to start associating.
    130   virtual void OnModelLoaded() = 0;
    131 
    132   virtual ~DataTypeController() {}
    133 
    134   // Handles the reporting of unrecoverable error. It records stuff in
    135   // UMA and reports to breakpad.
    136   // Virtual for testing purpose.
    137   virtual void RecordUnrecoverableError(
    138       const tracked_objects::Location& from_here,
    139       const std::string& message);
    140 };
    141 
    142 }  // namespace browser_sync
    143 
    144 #endif  // CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__
    145