Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 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. |
| 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 | |
| 22 | namespace syncer { |
| 23 | class SyncError; |
Torne (Richard Coles) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 24 | struct UserShare; |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 25 | } |
| 26 | |
Torne (Richard Coles) | 5f1c943 | 2014-08-12 13:47:38 +0100 | [diff] [blame] | 27 | namespace sync_driver { |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 28 | |
Torne (Richard Coles) | 010d83a | 2014-05-14 12:12:37 +0100 | [diff] [blame] | 29 | class ChangeProcessor; |
| 30 | |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 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 { |
| 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) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 54 | enum ConfigureResult { |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 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. |
Torne (Richard Coles) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 64 | RUNTIME_ERROR, // After starting, a runtime error was encountered. |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 65 | MAX_START_RESULT |
| 66 | }; |
| 67 | |
Torne (Richard Coles) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 68 | typedef base::Callback<void(ConfigureResult, |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 69 | const syncer::SyncMergeResult&, |
| 70 | const syncer::SyncMergeResult&)> StartCallback; |
| 71 | |
| 72 | typedef base::Callback<void(syncer::ModelType, |
| 73 | syncer::SyncError)> ModelLoadCallback; |
| 74 | |
Torne (Richard Coles) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 75 | typedef base::Callback<void(const tracked_objects::Location& location, |
| 76 | const std::string&)> DisableTypeCallback; |
| 77 | |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 78 | 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) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 84 | static bool IsUnrecoverableResult(ConfigureResult result); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 85 | |
| 86 | // Returns true if the datatype started successfully. |
Torne (Richard Coles) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 87 | static bool IsSuccessfulResult(ConfigureResult result); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 88 | |
| 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) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 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. |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 109 | 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) | 010d83a | 2014-05-14 12:12:37 +0100 | [diff] [blame] | 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; |
| 125 | |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 126 | // 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) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 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); |
| 139 | |
Torne (Richard Coles) | 6d86b77 | 2014-06-25 10:30:53 +0100 | [diff] [blame] | 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; |
| 146 | |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 147 | 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) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 152 | const base::Closure& error_callback); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 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 | |
Torne (Richard Coles) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 161 | syncer::UserShare* user_share() const; |
Torne (Richard Coles) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 162 | |
| 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) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 166 | |
| 167 | private: |
Torne (Richard Coles) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 168 | syncer::UserShare* user_share_; |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 169 | }; |
| 170 | |
Torne (Richard Coles) | 5f1c943 | 2014-08-12 13:47:38 +0100 | [diff] [blame] | 171 | } // namespace sync_driver |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 172 | |
| 173 | #endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__ |