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