blob: a673b1f473d1bd044a0ae9a51da2272c0e2d07c1 [file] [log] [blame]
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00001// 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
22namespace syncer {
23class SyncError;
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +010024struct UserShare;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000025}
26
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +010027namespace sync_driver {
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000028
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +010029class ChangeProcessor;
30
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000031// Data type controllers need to be refcounted threadsafe, as they may
32// need to run model associator or change processor on other threads.
33class 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
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +010054 enum ConfigureResult {
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000055 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.
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +010064 RUNTIME_ERROR, // After starting, a runtime error was encountered.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000065 MAX_START_RESULT
66 };
67
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +010068 typedef base::Callback<void(ConfigureResult,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000069 const syncer::SyncMergeResult&,
70 const syncer::SyncMergeResult&)> StartCallback;
71
72 typedef base::Callback<void(syncer::ModelType,
73 syncer::SyncError)> ModelLoadCallback;
74
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +010075 typedef base::Callback<void(const tracked_objects::Location& location,
76 const std::string&)> DisableTypeCallback;
77
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000078 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.
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +010084 static bool IsUnrecoverableResult(ConfigureResult result);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000085
86 // Returns true if the datatype started successfully.
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +010087 static bool IsSuccessfulResult(ConfigureResult result);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000088
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.
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +0100104 // 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.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000109 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
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +0100122 // 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
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000126 // 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
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +0100136 // 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
Torne (Richard Coles)6d86b772014-06-25 10:30:53 +0100140 // 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
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000147 protected:
148 friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>;
149 friend class base::DeleteHelper<DataTypeController>;
150
151 DataTypeController(scoped_refptr<base::MessageLoopProxy> ui_thread,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100152 const base::Closure& error_callback);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000153
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
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +0100161 syncer::UserShare* user_share() const;
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +0100162
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_;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000166
167 private:
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +0100168 syncer::UserShare* user_share_;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000169};
170
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +0100171} // namespace sync_driver
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000172
173#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__