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