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.
5 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_
6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_
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 "sync/internal_api/public/base/model_type.h"
16 #include "sync/internal_api/public/engine/model_safe_worker.h"
17 #include "sync/internal_api/public/sync_manager.h"
29 namespace browser_sync
{
31 class ChangeProcessor
;
34 // A class that keep track of the workers, change processors, and
35 // routing info for the enabled sync types, and also routes change
36 // events to the right processors.
37 class SyncBackendRegistrar
: public syncer::SyncManager::ChangeDelegate
{
39 // |name| is used for debugging. Does not take ownership of |profile| or
40 // |sync_loop|. Must be created on the UI thread.
41 SyncBackendRegistrar(const std::string
& name
,
43 base::MessageLoop
* sync_loop
);
45 // Informs the SyncBackendRegistrar of the currently enabled set of types.
46 // These types will be placed in the passive group. This function should be
47 // called exactly once during startup.
48 void SetInitialTypes(syncer::ModelTypeSet initial_types
);
50 // SyncBackendRegistrar must be destroyed as follows:
52 // 1) On the sync thread, call OnSyncerShutdownComplete() after
53 // the syncer is shutdown.
54 // 2) Meanwhile, on the UI thread, call StopOnUIThread(), which
55 // blocks until OnSyncerShutdownComplete() is called.
56 // 3) Destroy the SyncBackendRegistrar.
58 // This is to handle the complicated shutdown requirements of the
59 // UIModelWorker (since the UI thread is both the main thread and a
60 // thread which the syncer pushes changes to).
61 virtual ~SyncBackendRegistrar();
63 // Returns whether or not we are currently syncing encryption keys.
64 // Must be called on the UI thread.
65 bool IsNigoriEnabled() const;
67 // Removes all types in |types_to_remove| from the routing info and
68 // adds all the types in |types_to_add| to the routing info that are
69 // not already there (initially put in the passive group).
70 // |types_to_remove| and |types_to_add| must be disjoint. Returns
71 // the set of newly-added types. Must be called on the UI thread.
72 syncer::ModelTypeSet
ConfigureDataTypes(
73 syncer::ModelTypeSet types_to_add
,
74 syncer::ModelTypeSet types_to_remove
);
76 // Must be called from the UI thread. (See destructor comment.)
77 void StopOnUIThread();
79 // Must be called from the sync thread. (See destructor comment.)
80 void OnSyncerShutdownComplete();
82 // Activates the given data type (which should belong to the given
83 // group) and starts the given change processor. Must be called
84 // from |group|'s native thread.
85 void ActivateDataType(syncer::ModelType type
,
86 syncer::ModelSafeGroup group
,
87 ChangeProcessor
* change_processor
,
88 syncer::UserShare
* user_share
);
90 // Deactivates the given type if necessary. Must be called from the
91 // UI thread and not |type|'s native thread. Yes, this is
92 // surprising: see http://crbug.com/92804.
93 void DeactivateDataType(syncer::ModelType type
);
95 // Returns true only between calls to ActivateDataType(type, ...)
96 // and DeactivateDataType(type). Used only by tests.
97 bool IsTypeActivatedForTest(syncer::ModelType type
) const;
99 // SyncManager::ChangeDelegate implementation. May be called from
101 virtual void OnChangesApplied(
102 syncer::ModelType model_type
,
104 const syncer::BaseTransaction
* trans
,
105 const syncer::ImmutableChangeRecordList
& changes
) OVERRIDE
;
106 virtual void OnChangesComplete(syncer::ModelType model_type
) OVERRIDE
;
108 void GetWorkers(std::vector
<syncer::ModelSafeWorker
*>* out
);
109 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo
* out
);
112 typedef std::map
<syncer::ModelSafeGroup
,
113 scoped_refptr
<syncer::ModelSafeWorker
> > WorkerMap
;
115 // Returns the change processor for the given model, or NULL if none
116 // exists. Must be called from |group|'s native thread.
117 ChangeProcessor
* GetProcessor(syncer::ModelType type
) const;
119 // Must be called with |lock_| held. Simply returns the change
120 // processor for the given type, if it exists. May be called from
122 ChangeProcessor
* GetProcessorUnsafe(syncer::ModelType type
) const;
124 // Return true if |model_type| lives on the current thread. Must be
125 // called with |lock_| held. May be called on any thread.
126 bool IsCurrentThreadSafeForModel(
127 syncer::ModelType model_type
) const;
129 // Name used for debugging.
130 const std::string name_
;
132 Profile
* const profile_
;
134 base::MessageLoop
* const sync_loop_
;
136 const scoped_refptr
<UIModelWorker
> ui_worker_
;
138 bool stopped_on_ui_thread_
;
140 // Protects all variables below.
141 mutable base::Lock lock_
;
143 // We maintain ownership of all workers. In some cases, we need to
144 // ensure shutdown occurs in an expected sequence by Stop()ing
145 // certain workers. They are guaranteed to be valid because we only
146 // destroy elements of |workers_| after the syncapi has been
147 // destroyed. Unless a worker is no longer needed because all types
148 // that get routed to it have been disabled (from syncing). In that
149 // case, we'll destroy on demand *after* routing any dependent types
150 // to syncer::GROUP_PASSIVE, so that the syncapi doesn't call into garbage.
151 // If a key is present, it means at least one ModelType that routes
152 // to that model safe group is being synced.
154 syncer::ModelSafeRoutingInfo routing_info_
;
156 // The change processors that handle the different data types.
157 std::map
<syncer::ModelType
, ChangeProcessor
*> processors_
;
159 DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar
);
162 } // namespace browser_sync
164 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_