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_UI_DATA_TYPE_CONTROLLER_H_
6#define COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/compiler_specific.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/weak_ptr.h"
14#include "components/sync_driver/data_type_controller.h"
15#include "components/sync_driver/shared_change_processor.h"
16
17namespace base {
18class TimeDelta;
19}
20
21namespace syncer {
22class SyncableService;
23class SyncError;
24}
25
26namespace sync_driver {
27
28// Implementation for datatypes that reside on the (UI thread). This is the same
29// thread we perform initialization on, so we don't have to worry about thread
30// safety. The main start/stop funtionality is implemented by default.
31// Note: RefCountedThreadSafe by way of DataTypeController.
32class UIDataTypeController : public DataTypeController {
33 public:
34  UIDataTypeController(
35      scoped_refptr<base::MessageLoopProxy> ui_thread,
36      const base::Closure& error_callback,
37      syncer::ModelType type,
38      SyncApiComponentFactory* sync_factory);
39
40  // DataTypeController interface.
41  virtual void LoadModels(
42      const ModelLoadCallback& model_load_callback) OVERRIDE;
43  virtual void StartAssociating(const StartCallback& start_callback) OVERRIDE;
44  virtual void Stop() OVERRIDE;
45  virtual syncer::ModelType type() const OVERRIDE;
46  virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE;
47  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
48  virtual std::string name() const OVERRIDE;
49  virtual State state() const OVERRIDE;
50
51  // DataTypeErrorHandler interface.
52  virtual void OnSingleDataTypeUnrecoverableError(
53      const syncer::SyncError& error) OVERRIDE;
54
55  // Used by tests to override the factory used to create
56  // GenericChangeProcessors.
57  void SetGenericChangeProcessorFactoryForTest(
58      scoped_ptr<GenericChangeProcessorFactory> factory);
59
60 protected:
61  // For testing only.
62  UIDataTypeController();
63  // DataTypeController is RefCounted.
64  virtual ~UIDataTypeController();
65
66  // Start any dependent services that need to be running before we can
67  // associate models. The default implementation is a no-op.
68  // Return value:
69  //   True - if models are ready and association can proceed.
70  //   False - if models are not ready. OnModelLoaded() should be called when
71  //           the models are ready.
72  virtual bool StartModels();
73
74  // Perform any DataType controller specific state cleanup before stopping
75  // the datatype controller. The default implementation is a no-op.
76  virtual void StopModels();
77
78  // DataTypeController interface.
79  virtual void OnModelLoaded() OVERRIDE;
80
81  // Helper method for cleaning up state and invoking the start callback.
82  virtual void StartDone(ConfigureResult result,
83                         const syncer::SyncMergeResult& local_merge_result,
84                         const syncer::SyncMergeResult& syncer_merge_result);
85
86  // Record association time.
87  virtual void RecordAssociationTime(base::TimeDelta time);
88  // Record causes of start failure.
89  virtual void RecordStartFailure(ConfigureResult result);
90
91  SyncApiComponentFactory* const sync_factory_;
92
93  State state_;
94
95  StartCallback start_callback_;
96  ModelLoadCallback model_load_callback_;
97
98  // The sync datatype being controlled.
99  syncer::ModelType type_;
100
101  // Sync's interface to the datatype. All sync changes for |type_| are pushed
102  // through it to the datatype as well as vice versa.
103  //
104  // Lifetime: it gets created when Start()) is called, and a reference to it
105  // is passed to |local_service_| during Associate(). We release our reference
106  // when Stop() or StartFailed() is called, and |local_service_| releases its
107  // reference when local_service_->StopSyncing() is called or when it is
108  // destroyed.
109  //
110  // Note: we use refcounting here primarily so that we can keep a uniform
111  // SyncableService API, whether the datatype lives on the UI thread or not
112  // (a syncer::SyncableService takes ownership of its SyncChangeProcessor when
113  // MergeDataAndStartSyncing is called). This will help us eventually merge the
114  // two datatype controller implementations (for ui and non-ui thread
115  // datatypes).
116  scoped_refptr<SharedChangeProcessor> shared_change_processor_;
117
118  scoped_ptr<GenericChangeProcessorFactory> processor_factory_;
119
120  // A weak pointer to the actual local syncable service, which performs all the
121  // real work. We do not own the object.
122  base::WeakPtr<syncer::SyncableService> local_service_;
123
124  scoped_refptr<base::MessageLoopProxy> ui_thread_;
125 private:
126   // Associate the sync model with the service's model, then start syncing.
127  virtual void Associate();
128
129  virtual void AbortModelLoad();
130
131  DISALLOW_COPY_AND_ASSIGN(UIDataTypeController);
132};
133
134}  // namespace sync_driver
135
136#endif  // COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_
137