15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/data_type_error_handler.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_merge_result.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/model_safe_worker.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/unrecoverable_error_handler.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncError;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Data type controllers need to be refcounted threadsafe, as they may
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to run model associator or change processor on other threads.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DataTypeController
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DataTypeController, content::BrowserThread::DeleteOnUIThread>,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public DataTypeErrorHandler {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOT_RUNNING,    // The controller has never been started or has
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // previously been stopped.  Must be in this state to start.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_STARTING, // The controller is waiting on dependent services
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // that need to be available before model
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // association.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_LOADED,   // The model has finished loading and can start
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // associating now.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSOCIATING,    // Model association is in progress.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUNNING,        // The controller is running and the data type is
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // in sync with the cloud.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STOPPING,       // The controller is in the process of stopping
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // and is waiting for dependent services to stop.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISABLED        // The controller was started but encountered an error
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // so it is disabled waiting for it to be stopped.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum StartResult {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OK,                   // The data type has started normally.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OK_FIRST_RUN,         // Same as OK, but sent on first successful
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // start for this type for this user as
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // determined by cloud state.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BUSY,                 // Start() was called while already in progress.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOT_ENABLED,          // This data type is not enabled for the current user.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSOCIATION_FAILED,   // An error occurred during model association.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ABORTED,              // Start was aborted by calling Stop().
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNRECOVERABLE_ERROR,  // An unrecoverable error occured.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEEDS_CRYPTO,         // The data type cannot be started yet because it
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // depends on the cryptographer.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MAX_START_RESULT
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(StartResult,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const syncer::SyncMergeResult&,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const syncer::SyncMergeResult&)> StartCallback;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(syncer::ModelType,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              syncer::SyncError)> ModelLoadCallback;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<syncer::ModelType,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   scoped_refptr<DataTypeController> > TypeMap;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<syncer::ModelType, DataTypeController::State> StateMap;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the start result should trigger an unrecoverable error.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Public so unit tests can use this function as well.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsUnrecoverableResult(StartResult result);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the datatype started successfully.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool IsSuccessfulResult(StartResult result);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begins asynchronous operation of loading the model to get it ready for
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model association. Once the models are loaded the callback will be invoked
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with the result. If the models are already loaded it is safe to call the
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback right away. Else the callback needs to be stored and called when
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the models are ready.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will start a potentially asynchronous operation to perform the
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model association. Once the model association is done the callback will
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be invoked.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartAssociating(const StartCallback& start_callback) = 0;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Synchronously stops the data type. If StartAssociating has already been
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called but is not done yet it will be aborted. Similarly if LoadModels
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has not completed it will also be aborted.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop() = 0;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unique model type for this data type controller.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::ModelType type() const = 0;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Name of this data type.  For logging purposes only.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string name() const = 0;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The model safe group of this data type.  This should reflect the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread that should be used to modify the data type's native
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::ModelSafeGroup model_safe_group() const = 0;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Current state of the data type controller.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual State state() const = 0;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Partial implementation of DataTypeErrorHandler.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is thread safe.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::SyncError CreateAndUploadError(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& location,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& message,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syncer::ModelType type) OVERRIDE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct content::BrowserThread::DeleteOnThread<
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::UI>;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::DeleteHelper<DataTypeController>;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the DTC is waiting for models to load, once the models are
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loaded the datatype service will call this function on DTC to let
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us know that it is safe to start associating.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnModelLoaded() = 0;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DataTypeController() {}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the reporting of unrecoverable error. It records stuff in
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UMA and reports to breakpad.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Virtual for testing purpose.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RecordUnrecoverableError(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& from_here,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& message);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace browser_sync
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__
145