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