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 <memory>
10 #include <string>
11 #include <vector>
12 
13 #include "base/callback.h"
14 #include "base/location.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/sequence_checker.h"
17 #include "components/sync/base/model_type.h"
18 #include "components/sync/engine/shutdown_reason.h"
19 #include "components/sync/model/data_type_error_handler.h"
20 
21 namespace syncer {
22 
23 struct ConfigureContext;
24 struct TypeEntitiesCount;
25 class ModelTypeConfigurer;
26 class SyncError;
27 
28 // DataTypeControllers are responsible for managing the state of a single data
29 // type. They are not thread safe and should only be used on the UI thread.
30 class DataTypeController : public base::SupportsWeakPtr<DataTypeController> {
31  public:
32   enum State {
33     NOT_RUNNING,     // The controller has never been started or has previously
34                      // been stopped.  Must be in this state to start.
35     MODEL_STARTING,  // The model is loading.
36     MODEL_LOADED,    // The model has finished loading and can start running.
37     RUNNING,         // The controller is running and the data type is
38                      // in sync with the cloud.
39     STOPPING,        // The controller is in the process of stopping
40                      // and is waiting for dependent services to stop.
41     FAILED           // The controller was started but encountered an error.
42   };
43 
44   // Returned from ActivateDataType.
45   enum ActivateDataTypeResult {
46     // Indicates that the initial download for this type is already complete, or
47     // wasn't needed in the first place (e.g. for proxy types).
48     TYPE_ALREADY_DOWNLOADED,
49     // Indicates that the initial download for this type still needs to be done.
50     TYPE_NOT_YET_DOWNLOADED,
51   };
52 
53   // Note: This seems like it should be a OnceCallback, but it can actually be
54   // called multiple times in the case of errors.
55   using ModelLoadCallback =
56       base::RepeatingCallback<void(ModelType, const SyncError&)>;
57 
58   using StopCallback = base::OnceClosure;
59 
60   using AllNodesCallback =
61       base::OnceCallback<void(const ModelType,
62                               std::unique_ptr<base::ListValue>)>;
63 
64   using TypeMap = std::map<ModelType, std::unique_ptr<DataTypeController>>;
65   using TypeVector = std::vector<std::unique_ptr<DataTypeController>>;
66 
67   static std::string StateToString(State state);
68 
69   virtual ~DataTypeController();
70 
71   // Begins asynchronous operation of loading the model to get it ready for
72   // activation. Once the models are loaded the callback will be invoked with
73   // the result. If the models are already loaded it is safe to call the
74   // callback right away. Else the callback needs to be stored and called when
75   // the models are ready.
76   virtual void LoadModels(const ConfigureContext& configure_context,
77                           const ModelLoadCallback& model_load_callback) = 0;
78 
79   // Called by DataTypeManager once the local model has loaded, but before
80   // downloading initial data (if necessary). Returns whether the initial
81   // download for this type is already complete.
82   virtual ActivateDataTypeResult ActivateDataType(
83       ModelTypeConfigurer* configurer) = 0;
84 
85   // Called by DataTypeManager to deactivate the controlled data type.
86   // See comments for ModelAssociationManager::OnSingleDataTypeWillStop.
87   virtual void DeactivateDataType(ModelTypeConfigurer* configurer) = 0;
88 
89   // Stops the data type. If LoadModels() has not completed it will enter
90   // STOPPING state first and eventually STOPPED. Once stopped, |callback| will
91   // be run. |callback| must not be null.
92   //
93   // NOTE: Stop() should be called after sync backend machinery has stopped
94   // routing changes to this data type. Stop() should ensure the data type
95   // logic shuts down gracefully by flushing remaining changes and calling
96   // StopSyncing on the SyncableService. This assumes no changes will ever
97   // propagate from sync again from point where Stop() is called.
98   virtual void Stop(ShutdownReason shutdown_reason, StopCallback callback) = 0;
99 
100   // Name of this data type.  For logging purposes only.
name()101   std::string name() const { return ModelTypeToString(type()); }
102 
103   // Current state of the data type controller.
104   virtual State state() const = 0;
105 
106   // Unique model type for this data type controller.
type()107   ModelType type() const { return type_; }
108 
109   // Whether preconditions are met for the datatype to start. This is useful for
110   // example if the datatype depends on certain user preferences other than the
111   // ones for sync settings themselves.
112   enum class PreconditionState {
113     kPreconditionsMet,
114     kMustStopAndClearData,
115     kMustStopAndKeepData,
116   };
117   virtual PreconditionState GetPreconditionState() const;
118 
119   // Returns whether the datatype knows how to, and wants to, run in
120   // transport-only mode (see syncer::SyncMode enum).
121   virtual bool ShouldRunInTransportOnlyMode() const = 0;
122 
123   // Returns a ListValue representing all nodes for this data type through
124   // |callback| on this thread. Can only be called if state() != NOT_RUNNING.
125   // Used for populating nodes in Sync Node Browser of chrome://sync-internals.
126   virtual void GetAllNodes(AllNodesCallback callback) = 0;
127 
128   // Collects TypeEntitiesCount for this datatype and passes them to |callback|.
129   // Used to display entity counts in chrome://sync-internals.
130   virtual void GetTypeEntitiesCount(
131       base::OnceCallback<void(const TypeEntitiesCount&)> callback) const = 0;
132 
133   // Records entities count and estimated memory usage of the type into
134   // histograms. Can be called only if state() != NOT_RUNNING.
135   virtual void RecordMemoryUsageAndCountsHistograms() = 0;
136 
137  protected:
138   explicit DataTypeController(ModelType type);
139 
140   // Allows subclasses to DCHECK that they're on the correct sequence.
141   // TODO(crbug.com/846238): Rename this to CalledOnValidSequence.
142   bool CalledOnValidThread() const;
143 
144  private:
145   // The type this object is responsible for controlling.
146   const ModelType type_;
147 
148   // Used to check that functions are called on the correct sequence.
149   base::SequenceChecker sequence_checker_;
150 };
151 
152 }  // namespace syncer
153 
154 #endif  // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
155