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; 24 struct UserShare; 25 } 26 27 namespace sync_driver { 28 29 class ChangeProcessor; 30 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 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. 65 MAX_START_RESULT 66 }; 67 68 typedef base::Callback<void(ConfigureResult, 69 const syncer::SyncMergeResult&, 70 const syncer::SyncMergeResult&)> StartCallback; 71 72 typedef base::Callback<void(syncer::ModelType, 73 syncer::SyncError)> ModelLoadCallback; 74 75 typedef base::Callback<void(const tracked_objects::Location& location, 76 const std::string&)> DisableTypeCallback; 77 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. 84 static bool IsUnrecoverableResult(ConfigureResult result); 85 86 // Returns true if the datatype started successfully. 87 static bool IsSuccessfulResult(ConfigureResult result); 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. 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; 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 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 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 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 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 147 protected: 148 friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>; 149 friend class base::DeleteHelper<DataTypeController>; 150 151 DataTypeController(scoped_refptr<base::MessageLoopProxy> ui_thread, 152 const base::Closure& error_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 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_; 166 167 private: 168 syncer::UserShare* user_share_; 169 }; 170 171 } // namespace sync_driver 172 173 #endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__ 174