15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/data_type_error_handler.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_merge_result.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/model_safe_worker.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/unrecoverable_error_handler.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncError; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Data type controllers need to be refcounted threadsafe, as they may 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to run model associator or change processor on other threads. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DataTypeController 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe< 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataTypeController, content::BrowserThread::DeleteOnUIThread>, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public DataTypeErrorHandler { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOT_RUNNING, // The controller has never been started or has 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previously been stopped. Must be in this state to start. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_STARTING, // The controller is waiting on dependent services 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that need to be available before model 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // association. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_LOADED, // The model has finished loading and can start 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associating now. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSOCIATING, // Model association is in progress. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUNNING, // The controller is running and the data type is 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in sync with the cloud. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STOPPING, // The controller is in the process of stopping 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and is waiting for dependent services to stop. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISABLED // The controller was started but encountered an error 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so it is disabled waiting for it to be stopped. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum StartResult { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OK, // The data type has started normally. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OK_FIRST_RUN, // Same as OK, but sent on first successful 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // start for this type for this user as 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // determined by cloud state. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUSY, // Start() was called while already in progress. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOT_ENABLED, // This data type is not enabled for the current user. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSOCIATION_FAILED, // An error occurred during model association. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ABORTED, // Start was aborted by calling Stop(). 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNRECOVERABLE_ERROR, // An unrecoverable error occured. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEEDS_CRYPTO, // The data type cannot be started yet because it 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // depends on the cryptographer. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAX_START_RESULT 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(StartResult, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult&, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult&)> StartCallback; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(syncer::ModelType, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError)> ModelLoadCallback; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<syncer::ModelType, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<DataTypeController> > TypeMap; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<syncer::ModelType, DataTypeController::State> StateMap; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the start result should trigger an unrecoverable error. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Public so unit tests can use this function as well. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsUnrecoverableResult(StartResult result); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if the datatype started successfully. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool IsSuccessfulResult(StartResult result); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begins asynchronous operation of loading the model to get it ready for 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // model association. Once the models are loaded the callback will be invoked 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the result. If the models are already loaded it is safe to call the 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback right away. Else the callback needs to be stored and called when 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the models are ready. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will start a potentially asynchronous operation to perform the 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // model association. Once the model association is done the callback will 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be invoked. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StartAssociating(const StartCallback& start_callback) = 0; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synchronously stops the data type. If StartAssociating has already been 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called but is not done yet it will be aborted. Similarly if LoadModels 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has not completed it will also be aborted. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Stop() = 0; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unique model type for this data type controller. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelType type() const = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Name of this data type. For logging purposes only. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string name() const = 0; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The model safe group of this data type. This should reflect the 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread that should be used to modify the data type's native 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // model. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelSafeGroup model_safe_group() const = 0; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Current state of the data type controller. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual State state() const = 0; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Partial implementation of DataTypeErrorHandler. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is thread safe. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::SyncError CreateAndUploadError( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& location, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::ModelType type) OVERRIDE; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct content::BrowserThread::DeleteOnThread< 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::UI>; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::DeleteHelper<DataTypeController>; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the DTC is waiting for models to load, once the models are 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loaded the datatype service will call this function on DTC to let 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // us know that it is safe to start associating. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnModelLoaded() = 0; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DataTypeController() {} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles the reporting of unrecoverable error. It records stuff in 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UMA and reports to breakpad. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Virtual for testing purpose. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordUnrecoverableError( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SYNC_GLUE_DATA_TYPE_CONTROLLER_H__ 145