1// Copyright (c) 2012 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 CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__ 6#define CHROME_BROWSER_SYNC_GLUE_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/sequenced_task_runner_helpers.h" 14#include "chrome/browser/sync/glue/data_type_error_handler.h" 15#include "content/public/browser/browser_thread.h" 16#include "sync/api/sync_merge_result.h" 17#include "sync/internal_api/public/base/model_type.h" 18#include "sync/internal_api/public/engine/model_safe_worker.h" 19#include "sync/internal_api/public/util/unrecoverable_error_handler.h" 20 21namespace syncer { 22class SyncError; 23} 24 25namespace browser_sync { 26 27// Data type controllers need to be refcounted threadsafe, as they may 28// need to run model associator or change processor on other threads. 29class DataTypeController 30 : public base::RefCountedThreadSafe< 31 DataTypeController, content::BrowserThread::DeleteOnUIThread>, 32 public DataTypeErrorHandler { 33 public: 34 enum State { 35 NOT_RUNNING, // The controller has never been started or has 36 // previously been stopped. Must be in this state to start. 37 MODEL_STARTING, // The controller is waiting on dependent services 38 // that need to be available before model 39 // association. 40 MODEL_LOADED, // The model has finished loading and can start 41 // associating now. 42 ASSOCIATING, // Model association is in progress. 43 RUNNING, // The controller is running and the data type is 44 // in sync with the cloud. 45 STOPPING, // The controller is in the process of stopping 46 // and is waiting for dependent services to stop. 47 DISABLED // The controller was started but encountered an error 48 // so it is disabled waiting for it to be stopped. 49 }; 50 51 enum StartResult { 52 OK, // The data type has started normally. 53 OK_FIRST_RUN, // Same as OK, but sent on first successful 54 // start for this type for this user as 55 // determined by cloud state. 56 BUSY, // Start() was called while already in progress. 57 NOT_ENABLED, // This data type is not enabled for the current user. 58 ASSOCIATION_FAILED, // An error occurred during model association. 59 ABORTED, // Start was aborted by calling Stop(). 60 UNRECOVERABLE_ERROR, // An unrecoverable error occured. 61 NEEDS_CRYPTO, // The data type cannot be started yet because it 62 // depends on the cryptographer. 63 MAX_START_RESULT 64 }; 65 66 typedef base::Callback<void(StartResult, 67 const syncer::SyncMergeResult&, 68 const syncer::SyncMergeResult&)> StartCallback; 69 70 typedef base::Callback<void(syncer::ModelType, 71 syncer::SyncError)> ModelLoadCallback; 72 73 typedef std::map<syncer::ModelType, 74 scoped_refptr<DataTypeController> > TypeMap; 75 typedef std::map<syncer::ModelType, DataTypeController::State> StateMap; 76 77 // Returns true if the start result should trigger an unrecoverable error. 78 // Public so unit tests can use this function as well. 79 static bool IsUnrecoverableResult(StartResult result); 80 81 // Returns true if the datatype started successfully. 82 static bool IsSuccessfulResult(StartResult result); 83 84 // Begins asynchronous operation of loading the model to get it ready for 85 // model association. Once the models are loaded the callback will be invoked 86 // with the result. If the models are already loaded it is safe to call the 87 // callback right away. Else the callback needs to be stored and called when 88 // the models are ready. 89 virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0; 90 91 // Will start a potentially asynchronous operation to perform the 92 // model association. Once the model association is done the callback will 93 // be invoked. 94 virtual void StartAssociating(const StartCallback& start_callback) = 0; 95 96 // Synchronously stops the data type. If StartAssociating has already been 97 // called but is not done yet it will be aborted. Similarly if LoadModels 98 // has not completed it will also be aborted. 99 virtual void Stop() = 0; 100 101 // Unique model type for this data type controller. 102 virtual syncer::ModelType type() const = 0; 103 104 // Name of this data type. For logging purposes only. 105 virtual std::string name() const = 0; 106 107 // The model safe group of this data type. This should reflect the 108 // thread that should be used to modify the data type's native 109 // model. 110 virtual syncer::ModelSafeGroup model_safe_group() const = 0; 111 112 // Current state of the data type controller. 113 virtual State state() const = 0; 114 115 // Partial implementation of DataTypeErrorHandler. 116 // This is thread safe. 117 virtual syncer::SyncError CreateAndUploadError( 118 const tracked_objects::Location& location, 119 const std::string& message, 120 syncer::ModelType type) OVERRIDE; 121 122 protected: 123 friend struct content::BrowserThread::DeleteOnThread< 124 content::BrowserThread::UI>; 125 friend class base::DeleteHelper<DataTypeController>; 126 127 // If the DTC is waiting for models to load, once the models are 128 // loaded the datatype service will call this function on DTC to let 129 // us know that it is safe to start associating. 130 virtual void OnModelLoaded() = 0; 131 132 virtual ~DataTypeController() {} 133 134 // Handles the reporting of unrecoverable error. It records stuff in 135 // UMA and reports to breakpad. 136 // Virtual for testing purpose. 137 virtual void RecordUnrecoverableError( 138 const tracked_objects::Location& from_here, 139 const std::string& message); 140}; 141 142} // namespace browser_sync 143 144#endif // CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__ 145