summaryrefslogtreecommitdiffstats
path: root/components/sync_driver/non_ui_data_type_controller.h
blob: 2ea7dc8ec3f5bf606614be4a3f08193bff851280 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_
#define COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_

#include <string>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "components/sync_driver/data_type_controller.h"
#include "components/sync_driver/shared_change_processor.h"

namespace syncer {
class SyncableService;
}

namespace sync_driver {

class SyncApiComponentFactory;

class NonUIDataTypeController : public DataTypeController {
 public:
  NonUIDataTypeController(
      scoped_refptr<base::SingleThreadTaskRunner> ui_thread,
      const base::Closure& error_callback,
      SyncApiComponentFactory* sync_factory);

  // DataTypeController interface.
  void LoadModels(const ModelLoadCallback& model_load_callback) override;
  void StartAssociating(const StartCallback& start_callback) override;
  void Stop() override;
  syncer::ModelType type() const override = 0;
  syncer::ModelSafeGroup model_safe_group() const override = 0;
  ChangeProcessor* GetChangeProcessor() const override;
  std::string name() const override;
  State state() const override;
  void OnSingleDataTypeUnrecoverableError(
      const syncer::SyncError& error) override;

 protected:
  // For testing only.
  NonUIDataTypeController();
  // DataTypeController is RefCounted.
  ~NonUIDataTypeController() override;

  // DataTypeController interface.
  void OnModelLoaded() override;

  // Start any dependent services that need to be running before we can
  // associate models. The default implementation is a no-op.
  // Return value:
  //   True - if models are ready and association can proceed.
  //   False - if models are not ready. StartAssociationAsync should be called
  //           when the models are ready.
  // Note: this is performed on the UI thread.
  virtual bool StartModels();

  // Perform any DataType controller specific state cleanup before stopping
  // the datatype controller. The default implementation is a no-op.
  // Note: this is performed on the UI thread.
  virtual void StopModels();

  // Posts the given task to the backend thread, i.e. the thread the
  // datatype lives on.  Return value: True if task posted successfully,
  // false otherwise.
  virtual bool PostTaskOnBackendThread(
      const tracked_objects::Location& from_here,
      const base::Closure& task) = 0;

  // Start up complete, update the state and invoke the callback.
  // Note: this is performed on the datatype's thread.
  virtual void StartDone(
      DataTypeController::ConfigureResult start_result,
      const syncer::SyncMergeResult& local_merge_result,
      const syncer::SyncMergeResult& syncer_merge_result);

  // UI thread implementation of StartDone.
  virtual void StartDoneImpl(
      DataTypeController::ConfigureResult start_result,
      DataTypeController::State new_state,
      const syncer::SyncMergeResult& local_merge_result,
      const syncer::SyncMergeResult& syncer_merge_result);

  // Kick off the association process.
  virtual bool StartAssociationAsync();

  // Record association time.
  virtual void RecordAssociationTime(base::TimeDelta time);

  // Record causes of start failure.
  virtual void RecordStartFailure(ConfigureResult result);

  // To allow unit tests to control thread interaction during non-ui startup
  // and shutdown, use a factory method to create the SharedChangeProcessor.
  virtual SharedChangeProcessor* CreateSharedChangeProcessor();

 private:

  // Posted on the backend thread by StartAssociationAsync().
  void StartAssociationWithSharedChangeProcessor(
      const scoped_refptr<SharedChangeProcessor>& shared_change_processor);

  // Calls Disconnect() on |shared_change_processor_|, then sets it to
  // NULL.  Must be called only by StartDoneImpl() or Stop() (on the
  // UI thread) and only after a call to Start() (i.e.,
  // |shared_change_processor_| must be non-NULL).
  void ClearSharedChangeProcessor();

  // Posts StopLocalService() to the datatype's thread.
  void StopLocalServiceAsync();

  // Calls local_service_->StopSyncing() and releases our references to it.
  void StopLocalService();

  // Abort model loading and trigger the model load callback.
  void AbortModelLoad();

  // Disable this type with the sync service. Should only be invoked in case of
  // an unrecoverable error.
  // Note: this is performed on the UI thread.
  void DisableImpl(const syncer::SyncError& error);

  SyncApiComponentFactory* const sync_factory_;

  // State of this datatype controller.
  State state_;

  // Callbacks for use when starting the datatype.
  StartCallback start_callback_;
  ModelLoadCallback model_load_callback_;

  // The shared change processor is the thread-safe interface to the
  // datatype.  We hold a reference to it from the UI thread so that
  // we can call Disconnect() on it from Stop()/StartDoneImpl().  Most
  // of the work is done on the backend thread, and in
  // StartAssociationWithSharedChangeProcessor() for this class in
  // particular.
  //
  // Lifetime: The SharedChangeProcessor object is created on the UI
  // thread and passed on to the backend thread.  This reference is
  // released on the UI thread in Stop()/StartDoneImpl(), but the
  // backend thread may still have references to it (which is okay,
  // since we call Disconnect() before releasing the UI thread
  // reference).
  scoped_refptr<SharedChangeProcessor> shared_change_processor_;

  // A weak pointer to the actual local syncable service, which performs all the
  // real work. We do not own the object, and it is only safe to access on the
  // DataType's thread.
  // Lifetime: it gets set in StartAssociationWithSharedChangeProcessor(...)
  // and released in StopLocalService().
  base::WeakPtr<syncer::SyncableService> local_service_;

  scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
};

}  // namespace sync_driver

#endif  // COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_