15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 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)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define COMPONENTS_SYNC_DRIVER_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"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/ref_counted.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/ref_counted_delete_on_message_loop.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/data_type_error_handler.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_merge_result.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/model_safe_worker.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/unrecoverable_error_handler.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncError;
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)struct UserShare;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace sync_driver {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ChangeProcessor;
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Data type controllers need to be refcounted threadsafe, as they may
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to run model associator or change processor on other threads.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DataTypeController
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public base::RefCountedDeleteOnMessageLoop<DataTypeController>,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public DataTypeErrorHandler {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOT_RUNNING,    // The controller has never been started or has
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // previously been stopped.  Must be in this state to start.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_STARTING, // The controller is waiting on dependent services
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // that need to be available before model
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // association.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_LOADED,   // The model has finished loading and can start
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // associating now.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSOCIATING,    // Model association is in progress.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUNNING,        // The controller is running and the data type is
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // in sync with the cloud.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STOPPING,       // The controller is in the process of stopping
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // and is waiting for dependent services to stop.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISABLED        // The controller was started but encountered an error
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // so it is disabled waiting for it to be stopped.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  enum ConfigureResult {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OK,                   // The data type has started normally.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OK_FIRST_RUN,         // Same as OK, but sent on first successful
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // start for this type for this user as
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // determined by cloud state.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSOCIATION_FAILED,   // An error occurred during model association.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ABORTED,              // Start was aborted by calling Stop().
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNRECOVERABLE_ERROR,  // An unrecoverable error occured.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEEDS_CRYPTO,         // The data type cannot be started yet because it
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // depends on the cryptographer.
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    RUNTIME_ERROR,        // After starting, a runtime error was encountered.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MAX_START_RESULT
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  typedef base::Callback<void(ConfigureResult,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const syncer::SyncMergeResult&,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const syncer::SyncMergeResult&)> StartCallback;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(syncer::ModelType,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              syncer::SyncError)> ModelLoadCallback;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  typedef base::Callback<void(const tracked_objects::Location& location,
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const std::string&)> DisableTypeCallback;
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<syncer::ModelType,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   scoped_refptr<DataTypeController> > TypeMap;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<syncer::ModelType, DataTypeController::State> StateMap;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the start result should trigger an unrecoverable error.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Public so unit tests can use this function as well.
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static bool IsUnrecoverableResult(ConfigureResult result);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the datatype started successfully.
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static bool IsSuccessfulResult(ConfigureResult result);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begins asynchronous operation of loading the model to get it ready for
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model association. Once the models are loaded the callback will be invoked
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with the result. If the models are already loaded it is safe to call the
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback right away. Else the callback needs to be stored and called when
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the models are ready.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will start a potentially asynchronous operation to perform the
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model association. Once the model association is done the callback will
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be invoked.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartAssociating(const StartCallback& start_callback) = 0;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Synchronously stops the data type. If StartAssociating has already been
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called but is not done yet it will be aborted. Similarly if LoadModels
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has not completed it will also be aborted.
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // NOTE: Stop() should be called after sync backend machinery has stopped
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // routing changes to this data type. Stop() should ensure the data type
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // logic shuts down gracefully by flushing remaining changes and calling
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // StopSyncing on the SyncableService. This assumes no changes will ever
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // propagate from sync again from point where Stop() is called.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop() = 0;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unique model type for this data type controller.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::ModelType type() const = 0;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Name of this data type.  For logging purposes only.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string name() const = 0;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The model safe group of this data type.  This should reflect the
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread that should be used to modify the data type's native
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::ModelSafeGroup model_safe_group() const = 0;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Access to the ChangeProcessor for the type being controlled by |this|.
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Returns NULL if the ChangeProcessor isn't created or connected.
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ChangeProcessor* GetChangeProcessor() const = 0;
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Current state of the data type controller.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual State state() const = 0;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Partial implementation of DataTypeErrorHandler.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is thread safe.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::SyncError CreateAndUploadError(
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& location,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& message,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syncer::ModelType type) OVERRIDE;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Called when the sync backend has initialized. |share| is the
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // UserShare handle to associate model data with.
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void OnUserShareReady(syncer::UserShare* share);
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Whether the DataTypeController is ready to start. This is useful if the
1416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // datatype itself must make the decision about whether it should be enabled
1426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // at all (and therefore whether the initial download of the sync data for
1436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // the type should be performed).
1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Returns true by default.
1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual bool ReadyForStart() const;
1466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::DeleteHelper<DataTypeController>;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DataTypeController(scoped_refptr<base::MessageLoopProxy> ui_thread,
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                     const base::Closure& error_callback);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the DTC is waiting for models to load, once the models are
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loaded the datatype service will call this function on DTC to let
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us know that it is safe to start associating.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnModelLoaded() = 0;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DataTypeController();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  syncer::UserShare* user_share() const;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The callback that will be invoked when an unrecoverable error occurs.
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(sync): protected for use by legacy controllers.
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Closure error_callback_;
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  syncer::UserShare* user_share_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace sync_driver
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
174