OLD | NEW |
| (Empty) |
1 // Copyright 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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ | |
6 #define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <map> | |
11 #include <memory> | |
12 #include <string> | |
13 #include <vector> | |
14 | |
15 #include "base/compiler_specific.h" | |
16 #include "base/macros.h" | |
17 #include "base/memory/ref_counted.h" | |
18 #include "base/synchronization/lock.h" | |
19 #include "base/threading/thread.h" | |
20 #include "components/sync/base/model_type.h" | |
21 #include "components/sync/core/sync_manager.h" | |
22 #include "components/sync/engine/model_safe_worker.h" | |
23 | |
24 class Profile; | |
25 | |
26 namespace base { | |
27 class MessageLoop; | |
28 } | |
29 | |
30 namespace syncer { | |
31 struct UserShare; | |
32 } // namespace syncer | |
33 | |
34 namespace sync_driver { | |
35 class ChangeProcessor; | |
36 class SyncClient; | |
37 } | |
38 | |
39 namespace browser_sync { | |
40 | |
41 class UIModelWorker; | |
42 | |
43 // A class that keep track of the workers, change processors, and | |
44 // routing info for the enabled sync types, and also routes change | |
45 // events to the right processors. | |
46 class SyncBackendRegistrar : public syncer::SyncManager::ChangeDelegate, | |
47 public syncer::WorkerLoopDestructionObserver { | |
48 public: | |
49 // |name| is used for debugging. Does not take ownership of |profile|. | |
50 // Must be created on the UI thread. | |
51 SyncBackendRegistrar( | |
52 const std::string& name, | |
53 sync_driver::SyncClient* sync_client, | |
54 std::unique_ptr<base::Thread> sync_thread, | |
55 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, | |
56 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, | |
57 const scoped_refptr<base::SingleThreadTaskRunner>& file_thread); | |
58 | |
59 // SyncBackendRegistrar must be destroyed as follows: | |
60 // | |
61 // 1) On the UI thread, call RequestWorkerStopOnUIThread(). | |
62 // 2) UI posts task to shut down syncer on sync thread. | |
63 // 3) If sync is disabled, call ReleaseSyncThread() on the UI thread. | |
64 // 3) UI posts SyncBackendRegistrar::ShutDown() on sync thread to | |
65 // unregister workers from observing destruction of their working loops. | |
66 // 4) Workers notify registrar when unregistration finishes or working | |
67 // loops are destroyed. Registrar destroys itself on last worker | |
68 // notification. Sync thread will be stopped if ownership was not | |
69 // released. | |
70 ~SyncBackendRegistrar() override; | |
71 | |
72 // Adds |type| to set of non-blocking types. These types are assigned to | |
73 // GROUP_NON_BLOCKING model safe group and will be treated differently in | |
74 // ModelTypeRegistry. Unlike directory types, non-blocking types always stay | |
75 // assigned to GROUP_NON_BLOCKING group. | |
76 void RegisterNonBlockingType(syncer::ModelType type); | |
77 | |
78 // Informs the SyncBackendRegistrar of the currently enabled set of types. | |
79 // These types will be placed in the passive group. This function should be | |
80 // called exactly once during startup. | |
81 void SetInitialTypes(syncer::ModelTypeSet initial_types); | |
82 | |
83 // Informs SyncBackendRegistrar about non-blocking type loaded from local | |
84 // storage. Initial sync was already performed for this type, therefore its | |
85 // data shouldn't be downloaded as part of configuration. | |
86 void AddRestoredNonBlockingType(syncer::ModelType type); | |
87 | |
88 // Returns whether or not we are currently syncing encryption keys. | |
89 // Must be called on the UI thread. | |
90 bool IsNigoriEnabled() const; | |
91 | |
92 // Removes all types in |types_to_remove| from the routing info and | |
93 // adds all the types in |types_to_add| to the routing info that are | |
94 // not already there (initially put in the passive group). | |
95 // |types_to_remove| and |types_to_add| must be disjoint. Returns | |
96 // the set of newly-added types. Must be called on the UI thread. | |
97 syncer::ModelTypeSet ConfigureDataTypes(syncer::ModelTypeSet types_to_add, | |
98 syncer::ModelTypeSet types_to_remove); | |
99 | |
100 // Returns the set of enabled types as of the last configuration. Note that | |
101 // this might be different from the current types in the routing info due | |
102 // to DeactiveDataType being called separately from ConfigureDataTypes. | |
103 syncer::ModelTypeSet GetLastConfiguredTypes() const; | |
104 | |
105 // Must be called from the UI thread. (See destructor comment.) | |
106 void RequestWorkerStopOnUIThread(); | |
107 | |
108 // Activates the given data type (which should belong to the given | |
109 // group) and starts the given change processor. Must be called | |
110 // from |group|'s native thread. | |
111 void ActivateDataType(syncer::ModelType type, | |
112 syncer::ModelSafeGroup group, | |
113 sync_driver::ChangeProcessor* change_processor, | |
114 syncer::UserShare* user_share); | |
115 | |
116 // Deactivates the given type if necessary. Must be called from the | |
117 // UI thread and not |type|'s native thread. Yes, this is | |
118 // surprising: see http://crbug.com/92804. | |
119 void DeactivateDataType(syncer::ModelType type); | |
120 | |
121 // Returns true only between calls to ActivateDataType(type, ...) | |
122 // and DeactivateDataType(type). Used only by tests. | |
123 bool IsTypeActivatedForTest(syncer::ModelType type) const; | |
124 | |
125 // SyncManager::ChangeDelegate implementation. May be called from | |
126 // any thread. | |
127 void OnChangesApplied( | |
128 syncer::ModelType model_type, | |
129 int64_t model_version, | |
130 const syncer::BaseTransaction* trans, | |
131 const syncer::ImmutableChangeRecordList& changes) override; | |
132 void OnChangesComplete(syncer::ModelType model_type) override; | |
133 | |
134 void GetWorkers(std::vector<scoped_refptr<syncer::ModelSafeWorker>>* out); | |
135 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out); | |
136 | |
137 // syncer::WorkerLoopDestructionObserver implementation. | |
138 void OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) override; | |
139 | |
140 // Release ownership of |sync_thread_|. Called when sync is disabled. | |
141 std::unique_ptr<base::Thread> ReleaseSyncThread(); | |
142 | |
143 // Unregister workers from loop destruction observation. | |
144 void Shutdown(); | |
145 | |
146 base::Thread* sync_thread(); | |
147 | |
148 private: | |
149 typedef std::map<syncer::ModelSafeGroup, | |
150 scoped_refptr<syncer::ModelSafeWorker>> WorkerMap; | |
151 typedef std::map<syncer::ModelType, sync_driver::ChangeProcessor*> | |
152 ProcessorMap; | |
153 | |
154 // Add a worker for |group| to the worker map if one can be created. | |
155 void MaybeAddWorker(syncer::ModelSafeGroup group); | |
156 | |
157 // Callback after workers unregister from observing destruction of their | |
158 // working loops. | |
159 void OnWorkerUnregistrationDone(syncer::ModelSafeGroup group); | |
160 | |
161 void RemoveWorker(syncer::ModelSafeGroup group); | |
162 | |
163 // Returns the change processor for the given model, or NULL if none | |
164 // exists. Must be called from |group|'s native thread. | |
165 sync_driver::ChangeProcessor* GetProcessor(syncer::ModelType type) const; | |
166 | |
167 // Must be called with |lock_| held. Simply returns the change | |
168 // processor for the given type, if it exists. May be called from | |
169 // any thread. | |
170 sync_driver::ChangeProcessor* GetProcessorUnsafe( | |
171 syncer::ModelType type) const; | |
172 | |
173 // Return true if |model_type| lives on the current thread. Must be | |
174 // called with |lock_| held. May be called on any thread. | |
175 bool IsCurrentThreadSafeForModel(syncer::ModelType model_type) const; | |
176 | |
177 // Returns true if the current thread is the native thread for the | |
178 // given group (or if it is undeterminable). | |
179 bool IsOnThreadForGroup(syncer::ModelType type, | |
180 syncer::ModelSafeGroup group) const; | |
181 | |
182 // Returns model safe group that should be assigned to type when it is first | |
183 // configured (before activation). Returns GROUP_PASSIVE for directory types | |
184 // and GROUP_NON_BLOCKING for non-blocking types. | |
185 syncer::ModelSafeGroup GetInitialGroupForType(syncer::ModelType type) const; | |
186 | |
187 // Name used for debugging. | |
188 const std::string name_; | |
189 | |
190 // A pointer to the sync client. | |
191 sync_driver::SyncClient* const sync_client_; | |
192 | |
193 // Protects all variables below. | |
194 mutable base::Lock lock_; | |
195 | |
196 // We maintain ownership of all workers. In some cases, we need to | |
197 // ensure shutdown occurs in an expected sequence by Stop()ing | |
198 // certain workers. They are guaranteed to be valid because we only | |
199 // destroy elements of |workers_| after the syncapi has been | |
200 // destroyed. Unless a worker is no longer needed because all types | |
201 // that get routed to it have been disabled (from syncing). In that | |
202 // case, we'll destroy on demand *after* routing any dependent types | |
203 // to syncer::GROUP_PASSIVE, so that the syncapi doesn't call into garbage. | |
204 // If a key is present, it means at least one ModelType that routes | |
205 // to that model safe group is being synced. | |
206 WorkerMap workers_; | |
207 syncer::ModelSafeRoutingInfo routing_info_; | |
208 | |
209 // The change processors that handle the different data types. | |
210 ProcessorMap processors_; | |
211 | |
212 // The types that were enabled as of the last configuration. Updated on each | |
213 // call to ConfigureDataTypes as well as SetInitialTypes. | |
214 syncer::ModelTypeSet last_configured_types_; | |
215 | |
216 // Parks stopped workers because they may still be referenced by syncer. | |
217 std::vector<scoped_refptr<syncer::ModelSafeWorker>> stopped_workers_; | |
218 | |
219 // References to the thread task runners that sync depends on. | |
220 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; | |
221 const scoped_refptr<base::SingleThreadTaskRunner> db_thread_; | |
222 const scoped_refptr<base::SingleThreadTaskRunner> file_thread_; | |
223 | |
224 // Declare |sync_thread_| at the end so that it will be destroyed before | |
225 // objects above because tasks on sync thread depend on those objects, | |
226 // e.g. Shutdown() depends on |lock_|, SyncManager::Init() depends on | |
227 // workers, etc. | |
228 std::unique_ptr<base::Thread> sync_thread_; | |
229 | |
230 // Set of types with non-blocking implementation (as opposed to directory | |
231 // based). | |
232 syncer::ModelTypeSet non_blocking_types_; | |
233 | |
234 DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar); | |
235 }; | |
236 | |
237 } // namespace browser_sync | |
238 | |
239 #endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ | |
OLD | NEW |