Fix build break
[chromium-blink-merge.git] / chrome / browser / sync / glue / sync_backend_host.h
blobf32709e1cfa6647cc1f4e54d3da20d38d171ef09
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_HOST_H_
6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
8 #include <string>
10 #include "base/basictypes.h"
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/threading/thread.h"
17 #include "chrome/browser/sync/glue/backend_data_type_configurer.h"
18 #include "chrome/browser/sync/glue/chrome_extensions_activity_monitor.h"
19 #include "content/public/browser/notification_observer.h"
20 #include "content/public/browser/notification_registrar.h"
21 #include "google_apis/gaia/google_service_auth_error.h"
22 #include "googleurl/src/gurl.h"
23 #include "sync/internal_api/public/base/model_type.h"
24 #include "sync/internal_api/public/configure_reason.h"
25 #include "sync/internal_api/public/engine/model_safe_worker.h"
26 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
27 #include "sync/internal_api/public/sync_encryption_handler.h"
28 #include "sync/internal_api/public/sync_manager.h"
29 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h"
30 #include "sync/internal_api/public/util/unrecoverable_error_handler.h"
31 #include "sync/internal_api/public/util/weak_handle.h"
32 #include "sync/notifier/invalidation_handler.h"
33 #include "sync/notifier/invalidator_factory.h"
34 #include "sync/protocol/encryption.pb.h"
35 #include "sync/protocol/sync_protocol_error.h"
37 class Profile;
39 namespace base {
40 class MessageLoop;
43 namespace syncer {
44 class SyncManagerFactory;
47 namespace browser_sync {
49 class AndroidInvalidatorBridge;
50 class ChangeProcessor;
51 class InvalidatorStorage;
52 class SyncBackendRegistrar;
53 class SyncPrefs;
54 class SyncedDeviceTracker;
55 struct Experiments;
57 // SyncFrontend is the interface used by SyncBackendHost to communicate with
58 // the entity that created it and, presumably, is interested in sync-related
59 // activity.
60 // NOTE: All methods will be invoked by a SyncBackendHost on the same thread
61 // used to create that SyncBackendHost.
62 class SyncFrontend : public syncer::InvalidationHandler {
63 public:
64 SyncFrontend() {}
66 // The backend has completed initialization and it is now ready to
67 // accept and process changes. If success is false, initialization
68 // wasn't able to be completed and should be retried.
70 // |js_backend| is what about:sync interacts with; it's different
71 // from the 'Backend' in 'OnBackendInitialized' (unfortunately). It
72 // is initialized only if |success| is true.
73 virtual void OnBackendInitialized(
74 const syncer::WeakHandle<syncer::JsBackend>& js_backend,
75 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
76 debug_info_listener,
77 bool success) = 0;
79 // The backend queried the server recently and received some updates.
80 virtual void OnSyncCycleCompleted() = 0;
82 // Configure ran into some kind of error. But it is scheduled to be
83 // retried.
84 virtual void OnSyncConfigureRetry() = 0;
86 // The status of the connection to the sync server has changed.
87 virtual void OnConnectionStatusChange(
88 syncer::ConnectionStatus status) = 0;
90 // We are no longer permitted to communicate with the server. Sync should
91 // be disabled and state cleaned up at once.
92 virtual void OnStopSyncingPermanently() = 0;
94 // The syncer requires a passphrase to decrypt sensitive updates. This is
95 // called when the first sensitive data type is setup by the user and anytime
96 // the passphrase is changed by another synced client. |reason| denotes why
97 // the passphrase was required. |pending_keys| is a copy of the
98 // cryptographer's pending keys to be passed on to the frontend in order to
99 // be cached.
100 virtual void OnPassphraseRequired(
101 syncer::PassphraseRequiredReason reason,
102 const sync_pb::EncryptedData& pending_keys) = 0;
104 // Called when the passphrase provided by the user is
105 // accepted. After this is called, updates to sensitive nodes are
106 // encrypted using the accepted passphrase.
107 virtual void OnPassphraseAccepted() = 0;
109 // Called when the set of encrypted types or the encrypt everything
110 // flag has been changed. Note that encryption isn't complete until
111 // the OnEncryptionComplete() notification has been sent (see
112 // below).
114 // |encrypted_types| will always be a superset of
115 // syncer::Cryptographer::SensitiveTypes(). If |encrypt_everything| is
116 // true, |encrypted_types| will be the set of all known types.
118 // Until this function is called, observers can assume that the set
119 // of encrypted types is syncer::Cryptographer::SensitiveTypes() and that
120 // the encrypt everything flag is false.
121 virtual void OnEncryptedTypesChanged(
122 syncer::ModelTypeSet encrypted_types,
123 bool encrypt_everything) = 0;
125 // Called after we finish encrypting the current set of encrypted
126 // types.
127 virtual void OnEncryptionComplete() = 0;
129 // Called to perform migration of |types|.
130 virtual void OnMigrationNeededForTypes(syncer::ModelTypeSet types) = 0;
132 // Inform the Frontend that new datatypes are available for registration.
133 virtual void OnExperimentsChanged(
134 const syncer::Experiments& experiments) = 0;
136 // Called when the sync cycle returns there is an user actionable error.
137 virtual void OnActionableError(const syncer::SyncProtocolError& error) = 0;
139 protected:
140 // Don't delete through SyncFrontend interface.
141 virtual ~SyncFrontend() {
143 private:
144 DISALLOW_COPY_AND_ASSIGN(SyncFrontend);
147 // A UI-thread safe API into the sync backend that "hosts" the top-level
148 // syncapi element, the SyncManager, on its own thread. This class handles
149 // dispatch of potentially blocking calls to appropriate threads and ensures
150 // that the SyncFrontend is only accessed on the UI loop.
151 class SyncBackendHost
152 : public BackendDataTypeConfigurer,
153 public content::NotificationObserver {
154 public:
155 typedef syncer::SyncStatus Status;
157 // Create a SyncBackendHost with a reference to the |frontend| that
158 // it serves and communicates to via the SyncFrontend interface (on
159 // the same thread it used to call the constructor). Must outlive
160 // |sync_prefs| and |invalidator_storage|.
161 SyncBackendHost(
162 const std::string& name,
163 Profile* profile,
164 const base::WeakPtr<SyncPrefs>& sync_prefs,
165 // TODO(tim): Temporary, remove when bug 124137 finished.
166 const base::WeakPtr<InvalidatorStorage>& invalidator_storage);
168 // For testing.
169 // TODO(skrul): Extract an interface so this is not needed.
170 explicit SyncBackendHost(Profile* profile);
171 virtual ~SyncBackendHost();
173 // Called on |frontend_loop_| to kick off asynchronous initialization.
174 // As a fallback when no cached auth information is available, try to
175 // bootstrap authentication using |lsid|, if it isn't empty.
176 // Optionally delete the Sync Data folder (if it's corrupt).
177 // |report_unrecoverable_error_function| can be NULL.
178 // Note: |unrecoverable_error_handler| may be invoked from any thread.
179 void Initialize(
180 SyncFrontend* frontend,
181 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
182 const GURL& service_url,
183 const syncer::SyncCredentials& credentials,
184 bool delete_sync_data_folder,
185 syncer::SyncManagerFactory* sync_manager_factory,
186 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler,
187 syncer::ReportUnrecoverableErrorFunction
188 report_unrecoverable_error_function);
190 // Called on |frontend_loop| to update SyncCredentials.
191 virtual void UpdateCredentials(const syncer::SyncCredentials& credentials);
193 // Registers the underlying frontend for the given IDs to the underlying
194 // notifier. This lasts until StopSyncingForShutdown() is called.
195 void UpdateRegisteredInvalidationIds(const syncer::ObjectIdSet& ids);
197 // Forwards an invalidation acknowledgement to the underlying notifier.
198 void AcknowledgeInvalidation(const invalidation::ObjectId& id,
199 const syncer::AckHandle& ack_handle);
201 // This starts the SyncerThread running a Syncer object to communicate with
202 // sync servers. Until this is called, no changes will leave or enter this
203 // browser from the cloud / sync servers.
204 // Called on |frontend_loop_|.
205 virtual void StartSyncingWithServer();
207 // Called on |frontend_loop_| to asynchronously set a new passphrase for
208 // encryption. Note that it is an error to call SetEncryptionPassphrase under
209 // the following circumstances:
210 // - An explicit passphrase has already been set
211 // - |is_explicit| is true and we have pending keys.
212 // When |is_explicit| is false, a couple of things could happen:
213 // - If there are pending keys, we try to decrypt them. If decryption works,
214 // this acts like a call to SetDecryptionPassphrase. If not, the GAIA
215 // passphrase passed in is cached so we can re-encrypt with it in future.
216 // - If there are no pending keys, data is encrypted with |passphrase| (this
217 // is a no-op if data was already encrypted with |passphrase|.)
218 void SetEncryptionPassphrase(const std::string& passphrase, bool is_explicit);
220 // Called on |frontend_loop_| to use the provided passphrase to asynchronously
221 // attempt decryption. Returns false immediately if the passphrase could not
222 // be used to decrypt a locally cached copy of encrypted keys; returns true
223 // otherwise. If new encrypted keys arrive during the asynchronous call,
224 // OnPassphraseRequired may be triggered at a later time. It is an error to
225 // call this when there are no pending keys.
226 bool SetDecryptionPassphrase(const std::string& passphrase)
227 WARN_UNUSED_RESULT;
229 // Called on |frontend_loop_| to kick off shutdown procedure. After this, no
230 // further sync activity will occur with the sync server and no further
231 // change applications will occur from changes already downloaded.
232 // Furthermore, no notifications will be sent to any invalidation handler.
233 virtual void StopSyncingForShutdown();
235 // Called on |frontend_loop_| to kick off shutdown.
236 // |sync_disabled| indicates if syncing is being disabled or not.
237 // See the implementation and Core::DoShutdown for details.
238 // Must be called *after* StopSyncingForShutdown.
239 void Shutdown(bool sync_disabled);
241 // Changes the set of data types that are currently being synced.
242 // The ready_task will be run when configuration is done with the
243 // set of all types that failed configuration (i.e., if its argument
244 // is non-empty, then an error was encountered).
245 virtual void ConfigureDataTypes(
246 syncer::ConfigureReason reason,
247 const DataTypeConfigStateMap& config_state_map,
248 const base::Callback<void(syncer::ModelTypeSet)>& ready_task,
249 const base::Callback<void()>& retry_callback) OVERRIDE;
251 // Turns on encryption of all present and future sync data.
252 virtual void EnableEncryptEverything();
254 // Activates change processing for the given data type. This must
255 // be called synchronously with the data type's model association so
256 // no changes are dropped between model association and change
257 // processor activation.
258 void ActivateDataType(
259 syncer::ModelType type, syncer::ModelSafeGroup group,
260 ChangeProcessor* change_processor);
262 // Deactivates change processing for the given data type.
263 void DeactivateDataType(syncer::ModelType type);
265 // Called on |frontend_loop_| to obtain a handle to the UserShare needed for
266 // creating transactions. Should not be called before we signal
267 // initialization is complete with OnBackendInitialized().
268 syncer::UserShare* GetUserShare() const;
270 // Called from any thread to obtain current status information in detailed or
271 // summarized form.
272 Status GetDetailedStatus();
273 syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const;
275 // Determines if the underlying sync engine has made any local changes to
276 // items that have not yet been synced with the server.
277 // ONLY CALL THIS IF OnInitializationComplete was called!
278 bool HasUnsyncedItems() const;
280 // Whether or not we are syncing encryption keys.
281 bool IsNigoriEnabled() const;
283 // Returns the type of passphrase being used to encrypt data. See
284 // sync_encryption_handler.h.
285 syncer::PassphraseType GetPassphraseType() const;
287 // If an explicit passphrase is in use, returns the time at which that
288 // passphrase was set (if available).
289 base::Time GetExplicitPassphraseTime() const;
291 // True if the cryptographer has any keys available to attempt decryption.
292 // Could mean we've downloaded and loaded Nigori objects, or we bootstrapped
293 // using a token previously received.
294 bool IsCryptographerReady(const syncer::BaseTransaction* trans) const;
296 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out) const;
298 // Fetches the DeviceInfo tracker.
299 virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const;
301 protected:
302 // The types and functions below are protected so that test
303 // subclasses can use them.
305 // TODO(akalin): Figure out a better way for tests to hook into
306 // SyncBackendHost.
308 typedef base::Callback<scoped_ptr<syncer::HttpPostProviderFactory>(void)>
309 MakeHttpBridgeFactoryFn;
311 struct DoInitializeOptions {
312 DoInitializeOptions(
313 base::MessageLoop* sync_loop,
314 SyncBackendRegistrar* registrar,
315 const syncer::ModelSafeRoutingInfo& routing_info,
316 const std::vector<syncer::ModelSafeWorker*>& workers,
317 syncer::ExtensionsActivityMonitor* extensions_activity_monitor,
318 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
319 const GURL& service_url,
320 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn,
321 const syncer::SyncCredentials& credentials,
322 AndroidInvalidatorBridge* android_invalidator_bridge,
323 syncer::InvalidatorFactory* invalidator_factory,
324 syncer::SyncManagerFactory* sync_manager_factory,
325 bool delete_sync_data_folder,
326 const std::string& restored_key_for_bootstrapping,
327 const std::string& restored_keystore_key_for_bootstrapping,
328 syncer::InternalComponentsFactory* internal_components_factory,
329 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler,
330 syncer::ReportUnrecoverableErrorFunction
331 report_unrecoverable_error_function);
332 ~DoInitializeOptions();
334 base::MessageLoop* sync_loop;
335 SyncBackendRegistrar* registrar;
336 syncer::ModelSafeRoutingInfo routing_info;
337 std::vector<syncer::ModelSafeWorker*> workers;
338 syncer::ExtensionsActivityMonitor* extensions_activity_monitor;
339 syncer::WeakHandle<syncer::JsEventHandler> event_handler;
340 GURL service_url;
341 // Overridden by tests.
342 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn;
343 syncer::SyncCredentials credentials;
344 AndroidInvalidatorBridge* const android_invalidator_bridge;
345 syncer::InvalidatorFactory* const invalidator_factory;
346 syncer::SyncManagerFactory* const sync_manager_factory;
347 std::string lsid;
348 bool delete_sync_data_folder;
349 std::string restored_key_for_bootstrapping;
350 std::string restored_keystore_key_for_bootstrapping;
351 syncer::InternalComponentsFactory* internal_components_factory;
352 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler;
353 syncer::ReportUnrecoverableErrorFunction
354 report_unrecoverable_error_function;
357 // Allows tests to perform alternate core initialization work.
358 virtual void InitCore(const DoInitializeOptions& options);
360 // Request the syncer to reconfigure with the specfied params.
361 // Virtual for testing.
362 virtual void RequestConfigureSyncer(
363 syncer::ConfigureReason reason,
364 syncer::ModelTypeSet types_to_config,
365 syncer::ModelTypeSet failed_types,
366 const syncer::ModelSafeRoutingInfo& routing_info,
367 const base::Callback<void(syncer::ModelTypeSet)>& ready_task,
368 const base::Closure& retry_callback);
370 // Called when the syncer has finished performing a configuration.
371 void FinishConfigureDataTypesOnFrontendLoop(
372 const syncer::ModelTypeSet failed_configuration_types,
373 const base::Callback<void(syncer::ModelTypeSet)>& ready_task);
375 // Called when the SyncManager has been constructed and initialized.
376 // Stores |js_backend| and |debug_info_listener| on the UI thread for
377 // consumption when initialization is complete.
378 virtual void HandleSyncManagerInitializationOnFrontendLoop(
379 const syncer::WeakHandle<syncer::JsBackend>& js_backend,
380 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
381 debug_info_listener,
382 syncer::ModelTypeSet restored_types);
384 SyncFrontend* frontend() { return frontend_; }
386 private:
387 // The real guts of SyncBackendHost, to keep the public client API clean.
388 class Core;
390 // An enum representing the steps to initializing the SyncBackendHost.
391 enum InitializationState {
392 NOT_ATTEMPTED,
393 CREATING_SYNC_MANAGER, // We're waiting for the first callback from the
394 // sync thread to inform us that the sync
395 // manager has been created.
396 NOT_INITIALIZED, // Initialization hasn't completed, but we've
397 // constructed a SyncManager.
398 INITIALIZATING_CONTROL_TYPES, // Downloading control types and
399 // initializing their handlers.
400 INITIALIZED, // Initialization is complete.
403 // Checks if we have received a notice to turn on experimental datatypes
404 // (via the nigori node) and informs the frontend if that is the case.
405 // Note: it is illegal to call this before the backend is initialized.
406 void AddExperimentalTypes();
408 // Downloading of control types failed and will be retried. Invokes the
409 // frontend's sync configure retry method.
410 void HandleControlTypesDownloadRetry();
412 // InitializationComplete passes through the SyncBackendHost to forward
413 // on to |frontend_|, and so that tests can intercept here if they need to
414 // set up initial conditions.
415 void HandleInitializationCompletedOnFrontendLoop(
416 bool success);
418 // Called from Core::OnSyncCycleCompleted to handle updating frontend
419 // thread components.
420 void HandleSyncCycleCompletedOnFrontendLoop(
421 const syncer::sessions::SyncSessionSnapshot& snapshot);
423 // Called when the syncer failed to perform a configuration and will
424 // eventually retry. FinishingConfigurationOnFrontendLoop(..) will be called
425 // on successful completion.
426 void RetryConfigurationOnFrontendLoop(const base::Closure& retry_callback);
428 // Helpers to persist a token that can be used to bootstrap sync encryption
429 // across browser restart to avoid requiring the user to re-enter their
430 // passphrase. |token| must be valid UTF-8 as we use the PrefService for
431 // storage.
432 void PersistEncryptionBootstrapToken(
433 const std::string& token,
434 syncer::BootstrapTokenType token_type);
436 // For convenience, checks if initialization state is INITIALIZED.
437 bool initialized() const { return initialization_state_ == INITIALIZED; }
439 // Let the front end handle the actionable error event.
440 void HandleActionableErrorEventOnFrontendLoop(
441 const syncer::SyncProtocolError& sync_error);
443 // Checks if |passphrase| can be used to decrypt the cryptographer's pending
444 // keys that were cached during NotifyPassphraseRequired. Returns true if
445 // decryption was successful. Returns false otherwise. Must be called with a
446 // non-empty pending keys cache.
447 bool CheckPassphraseAgainstCachedPendingKeys(
448 const std::string& passphrase) const;
450 // Invoked when a passphrase is required to decrypt a set of Nigori keys,
451 // or for encrypting. |reason| denotes why the passphrase was required.
452 // |pending_keys| is a copy of the cryptographer's pending keys, that are
453 // cached by the frontend. If there are no pending keys, or if the passphrase
454 // required reason is REASON_ENCRYPTION, an empty EncryptedData object is
455 // passed.
456 void NotifyPassphraseRequired(syncer::PassphraseRequiredReason reason,
457 sync_pb::EncryptedData pending_keys);
459 // Invoked when the passphrase provided by the user has been accepted.
460 void NotifyPassphraseAccepted();
462 // Invoked when an updated token is available from the sync server.
463 void NotifyUpdatedToken(const std::string& token);
465 // Invoked when the set of encrypted types or the encrypt
466 // everything flag changes.
467 void NotifyEncryptedTypesChanged(
468 syncer::ModelTypeSet encrypted_types,
469 bool encrypt_everything);
471 // Invoked when sync finishes encrypting new datatypes.
472 void NotifyEncryptionComplete();
474 // Invoked when the passphrase state has changed. Caches the passphrase state
475 // for later use on the UI thread.
476 // If |type| is FROZEN_IMPLICIT_PASSPHRASE or CUSTOM_PASSPHRASE,
477 // |explicit_passphrase_time| is the time at which that passphrase was set
478 // (if available).
479 void HandlePassphraseTypeChangedOnFrontendLoop(
480 syncer::PassphraseType type,
481 base::Time explicit_passphrase_time);
483 void HandleStopSyncingPermanentlyOnFrontendLoop();
485 // Dispatched to from OnConnectionStatusChange to handle updating
486 // frontend UI components.
487 void HandleConnectionStatusChangeOnFrontendLoop(
488 syncer::ConnectionStatus status);
490 // syncer::InvalidationHandler-like functions.
491 void HandleInvalidatorStateChangeOnFrontendLoop(
492 syncer::InvalidatorState state);
493 void HandleIncomingInvalidationOnFrontendLoop(
494 const syncer::ObjectIdInvalidationMap& invalidation_map);
496 // NotificationObserver implementation.
497 virtual void Observe(
498 int type,
499 const content::NotificationSource& source,
500 const content::NotificationDetails& details) OVERRIDE;
502 // Handles stopping the core's SyncManager, accounting for whether
503 // initialization is done yet.
504 void StopSyncManagerForShutdown(const base::Closure& closure);
506 base::WeakPtrFactory<SyncBackendHost> weak_ptr_factory_;
508 content::NotificationRegistrar notification_registrar_;
510 // A thread where all the sync operations happen.
511 base::Thread sync_thread_;
513 // A reference to the MessageLoop used to construct |this|, so we know how
514 // to safely talk back to the SyncFrontend.
515 base::MessageLoop* const frontend_loop_;
517 Profile* const profile_;
519 // Name used for debugging (set from profile_->GetDebugName()).
520 const std::string name_;
522 // Our core, which communicates directly to the syncapi.
523 scoped_refptr<Core> core_;
525 InitializationState initialization_state_;
527 const base::WeakPtr<SyncPrefs> sync_prefs_;
529 scoped_ptr<AndroidInvalidatorBridge> android_invalidator_bridge_;
531 syncer::InvalidatorFactory invalidator_factory_;
533 ChromeExtensionsActivityMonitor extensions_activity_monitor_;
535 scoped_ptr<SyncBackendRegistrar> registrar_;
537 // The frontend which we serve (and are owned by).
538 SyncFrontend* frontend_;
540 // We cache the cryptographer's pending keys whenever NotifyPassphraseRequired
541 // is called. This way, before the UI calls SetDecryptionPassphrase on the
542 // syncer, it can avoid the overhead of an asynchronous decryption call and
543 // give the user immediate feedback about the passphrase entered by first
544 // trying to decrypt the cached pending keys on the UI thread. Note that
545 // SetDecryptionPassphrase can still fail after the cached pending keys are
546 // successfully decrypted if the pending keys have changed since the time they
547 // were cached.
548 sync_pb::EncryptedData cached_pending_keys_;
550 // The state of the passphrase required to decrypt the bag of encryption keys
551 // in the nigori node. Updated whenever a new nigori node arrives or the user
552 // manually changes their passphrase state. Cached so we can synchronously
553 // check it from the UI thread.
554 syncer::PassphraseType cached_passphrase_type_;
556 // If an explicit passphrase is in use, the time at which the passphrase was
557 // first set (if available).
558 base::Time cached_explicit_passphrase_time_;
560 // UI-thread cache of the last SyncSessionSnapshot received from syncapi.
561 syncer::sessions::SyncSessionSnapshot last_snapshot_;
563 // Temporary holder of sync manager's initialization results. Set by
564 // HandleSyncManagerInitializationOnFrontendLoop, and consumed when we pass
565 // it via OnBackendInitialized in the final state of
566 // HandleInitializationCompletedOnFrontendLoop.
567 syncer::WeakHandle<syncer::JsBackend> js_backend_;
568 syncer::WeakHandle<syncer::DataTypeDebugInfoListener> debug_info_listener_;
570 DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
573 } // namespace browser_sync
575 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_