1 // 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.
5 #ifndef COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
6 #define COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
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"
27 namespace sync_driver {
29 class ChangeProcessor;
31 // Data type controllers need to be refcounted threadsafe, as they may
32 // need to run model associator or change processor on other threads.
33 class DataTypeController
34 : public base::RefCountedDeleteOnMessageLoop<DataTypeController>,
35 public DataTypeErrorHandler {
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
43 MODEL_LOADED, // The model has finished loading and can start
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.
54 enum ConfigureResult {
55 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.
64 RUNTIME_ERROR, // After starting, a runtime error was encountered.
68 typedef base::Callback<void(ConfigureResult,
69 const syncer::SyncMergeResult&,
70 const syncer::SyncMergeResult&)> StartCallback;
72 typedef base::Callback<void(syncer::ModelType,
73 syncer::SyncError)> ModelLoadCallback;
75 typedef base::Callback<void(const tracked_objects::Location& location,
76 const std::string&)> DisableTypeCallback;
78 typedef std::map<syncer::ModelType,
79 scoped_refptr<DataTypeController> > TypeMap;
80 typedef std::map<syncer::ModelType, DataTypeController::State> StateMap;
82 // Returns true if the start result should trigger an unrecoverable error.
83 // Public so unit tests can use this function as well.
84 static bool IsUnrecoverableResult(ConfigureResult result);
86 // Returns true if the datatype started successfully.
87 static bool IsSuccessfulResult(ConfigureResult result);
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;
96 // Will start a potentially asynchronous operation to perform the
97 // model association. Once the model association is done the callback will
99 virtual void StartAssociating(const StartCallback& start_callback) = 0;
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.
104 // 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.
109 virtual void Stop() = 0;
111 // Unique model type for this data type controller.
112 virtual syncer::ModelType type() const = 0;
114 // Name of this data type. For logging purposes only.
115 virtual std::string name() const = 0;
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
120 virtual syncer::ModelSafeGroup model_safe_group() const = 0;
122 // 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;
126 // Current state of the data type controller.
127 virtual State state() const = 0;
129 // Partial implementation of DataTypeErrorHandler.
130 // This is thread safe.
131 syncer::SyncError CreateAndUploadError(
132 const tracked_objects::Location& location,
133 const std::string& message,
134 syncer::ModelType type) override;
136 // Called when the sync backend has initialized. |share| is the
137 // UserShare handle to associate model data with.
138 void OnUserShareReady(syncer::UserShare* share);
140 // 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;
148 friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>;
149 friend class base::DeleteHelper<DataTypeController>;
151 DataTypeController(scoped_refptr<base::MessageLoopProxy> ui_thread,
152 const base::Closure& error_callback);
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;
159 ~DataTypeController() override;
161 syncer::UserShare* user_share() const;
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_;
168 syncer::UserShare* user_share_;
171 } // namespace sync_driver
173 #endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__