1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/gtest_prod_util.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h"
183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncapi.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/model_safe_worker.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/js_backend.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/js_sync_manager_observer.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/data_type_controller.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/ui_model_worker.h"
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/js_event_router.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/model_type.h"
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/google_service_auth_error.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CancelableTask;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass Profile;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace net {
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass URLRequestContextGetter;
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace sync_notifier {
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass SyncNotifier;
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace sync_notifier
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace sessions {
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SyncSessionSnapshot;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ChangeProcessor;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DataTypeController;
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass JsArgList;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SyncFrontend is the interface used by SyncBackendHost to communicate with
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the entity that created it and, presumably, is interested in sync-related
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// activity.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NOTE: All methods will be invoked by a SyncBackendHost on the same thread
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// used to create that SyncBackendHost.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SyncFrontend {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncFrontend() {}
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend has completed initialization and it is now ready to accept and
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // process changes.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnBackendInitialized() = 0;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend queried the server recently and received some updates.
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnSyncCycleCompleted() = 0;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend encountered an authentication problem and requests new
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // credentials to be provided. See SyncBackendHost::Authenticate for details.
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnAuthError() = 0;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We are no longer permitted to communicate with the server. Sync should
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be disabled and state cleaned up at once.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnStopSyncingPermanently() = 0;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Called to handle success/failure of clearing server data
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void OnClearServerDataSucceeded() = 0;
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void OnClearServerDataFailed() = 0;
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The syncer requires a passphrase to decrypt sensitive
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // updates. This is called when the first sensitive data type is
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // setup by the user as well as anytime any the passphrase is
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // changed in another synced client.  if
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // |passphrase_required_for_decryption| is false, the passphrase is
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // required only for encryption.
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void OnPassphraseRequired(bool for_decryption) = 0;
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Called when the passphrase provided by the user is
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // accepted. After this is called, updates to sensitive nodes are
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // encrypted using the accepted passphrase.
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void OnPassphraseAccepted() = 0;
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void OnEncryptionComplete(
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const syncable::ModelTypeSet& encrypted_types) = 0;
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Called to perform migration of |types|.
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnMigrationNeededForTypes(
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const syncable::ModelTypeSet& types) = 0;
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't delete through SyncFrontend interface.
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~SyncFrontend() {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncFrontend);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A UI-thread safe API into the sync backend that "hosts" the top-level
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// syncapi element, the SyncManager, on its own thread. This class handles
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// dispatch of potentially blocking calls to appropriate threads and ensures
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that the SyncFrontend is only accessed on the UI loop.
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef sync_api::SyncManager::Status::Summary StatusSummary;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef sync_api::SyncManager::Status Status;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::map<ModelSafeGroup,
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   scoped_refptr<browser_sync::ModelSafeWorker> > WorkerMap;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a SyncBackendHost with a reference to the |frontend| that it serves
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and communicates to via the SyncFrontend interface (on the same thread
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it used to call the constructor).
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  explicit SyncBackendHost(Profile* profile);
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For testing.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(skrul): Extract an interface so this is not needed.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncBackendHost();
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual ~SyncBackendHost();
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to kick off asynchronous initialization.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // As a fallback when no cached auth information is available, try to
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bootstrap authentication using |lsid|, if it isn't empty.
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Optionally delete the Sync Data folder (if it's corrupt).
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void Initialize(SyncFrontend* frontend,
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  const GURL& service_url,
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  const syncable::ModelTypeSet& types,
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  net::URLRequestContextGetter* baseline_context_getter,
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  const sync_api::SyncCredentials& credentials,
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  bool delete_sync_data_folder);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Called from |frontend_loop| to update SyncCredentials.
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void UpdateCredentials(const sync_api::SyncCredentials& credentials);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This starts the SyncerThread running a Syncer object to communicate with
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sync servers.  Until this is called, no changes will leave or enter this
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // browser from the cloud / sync servers.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_|.
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void StartSyncingWithServer();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to asynchronously set the passphrase.
1514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // |is_explicit| is true if the call is in response to the user explicitly
1524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // setting a passphrase as opposed to implicitly (from the users' perspective)
1534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // using their Google Account password.  An implicit SetPassphrase will *not*
1544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // *not* override an explicit passphrase set previously.
1554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void SetPassphrase(const std::string& passphrase, bool is_explicit);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to kick off shutdown.
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |sync_disabled| indicates if syncing is being disabled or not.
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // See the implementation and Core::DoShutdown for details.
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Shutdown(bool sync_disabled);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Changes the set of data types that are currently being synced.
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The ready_task will be run when all of the requested data types
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are up-to-date and ready for activation.  The task will cancelled
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // upon shutdown.  The method takes ownership of the task pointer.
16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void ConfigureDataTypes(
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const DataTypeController::TypeMap& data_type_controllers,
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const syncable::ModelTypeSet& types,
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CancelableTask* ready_task);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Makes an asynchronous call to syncer to switch to config mode. When done
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // syncer will call us back on FinishConfigureDataTypes.
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void StartConfiguration(Callback0::Type* callback);
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Encrypts the specified datatypes and marks them as needing encryption on
176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // other machines. This affects all machines synced to this account and all
177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // data belonging to the specified types.
178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Note: actual work is done on core_thread_'s message loop.
179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void EncryptDataTypes(
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const syncable::ModelTypeSet& encrypted_types);
181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  syncable::AutofillMigrationState
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      GetAutofillMigrationState();
18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void SetAutofillMigrationState(
18621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      syncable::AutofillMigrationState state);
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  syncable::AutofillMigrationDebugInfo
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      GetAutofillMigrationDebugInfo();
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void SetAutofillMigrationDebugInfo(
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set,
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const syncable::AutofillMigrationDebugInfo& info);
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Activates change processing for the given data type.  This must
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be called synchronously with the data type's model association so
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // no changes are dropped between model association and change
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // processor activation.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ActivateDataType(DataTypeController* data_type_controller,
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        ChangeProcessor* change_processor);
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Deactivates change processing for the given data type.
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void DeactivateDataType(DataTypeController* data_type_controller,
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          ChangeProcessor* change_processor);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Asks the server to clear all data associated with ChromeSync.
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual bool RequestClearServerData();
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to obtain a handle to the UserShare needed
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for creating transactions.
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  sync_api::UserShare* GetUserShare() const;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called from any thread to obtain current status information in detailed or
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // summarized form.
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Status GetDetailedStatus();
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatusSummary GetStatusSummary();
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GoogleServiceAuthError& GetAuthError() const;
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const sessions::SyncSessionSnapshot* GetLastSessionSnapshot() const;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath& sync_data_folder_path() const {
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return sync_data_folder_path_;
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the authenticated username of the sync user, or empty if none
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // exists. It will only exist if the authentication service provider (e.g
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // GAIA) has confirmed the username is authentic.
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 GetAuthenticatedUsername() const;
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ModelSafeWorkerRegistrar implementation.
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetWorkers(std::vector<browser_sync::ModelSafeWorker*>* out);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Determines if the underlying sync engine has made any local changes to
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // items that have not yet been synced with the server.
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // ONLY CALL THIS IF OnInitializationComplete was called!
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool HasUnsyncedItems() const;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Whether or not we are syncing encryption keys.
239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool IsNigoriEnabled() const;
240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Whether or not the Nigori node is encrypted using an explicit passphrase.
2424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool IsUsingExplicitPassphrase();
2434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // True if the cryptographer has any keys available to attempt decryption.
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Could mean we've downloaded and loaded Nigori objects, or we bootstrapped
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // using a token previously received.
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool IsCryptographerReady(const sync_api::BaseTransaction* trans) const;
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Returns a pointer to the JsBackend (which is owned by the
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // service).  Must be called only after the sync backend has been
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // initialized, and never returns NULL if you do so.  Overrideable
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // for testing purposes.
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual JsBackend* GetJsBackend();
25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // TODO(akalin): Write unit tests for the JsBackend, finding a way
25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // to make this class testable in general.
25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick protected:
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The real guts of SyncBackendHost, to keep the public client API clean.
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Core : public base::RefCountedThreadSafe<SyncBackendHost::Core>,
26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen               public sync_api::SyncManager::Observer,
26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen               public JsBackend,
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen               public JsEventRouter {
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    explicit Core(SyncBackendHost* backend);
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // SyncManager::Observer implementation.  The Core just acts like an air
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // traffic controller here, forwarding incoming messages to appropriate
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // landing threads.
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnChangesApplied(
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        syncable::ModelType model_type,
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const sync_api::BaseTransaction* trans,
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const sync_api::SyncManager::ChangeRecord* changes,
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        int change_count);
2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnChangesComplete(syncable::ModelType model_type);
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnSyncCycleCompleted(
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const sessions::SyncSessionSnapshot* snapshot);
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnInitializationComplete();
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnAuthError(const GoogleServiceAuthError& auth_error);
280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    virtual void OnPassphraseRequired(bool for_decryption);
281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    virtual void OnPassphraseFailed();
2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnPassphraseAccepted(const std::string& bootstrap_token);
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnStopSyncingPermanently();
2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnUpdatedToken(const std::string& token);
2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnClearServerDataFailed();
2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual void OnClearServerDataSucceeded();
287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    virtual void OnEncryptionComplete(
288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        const syncable::ModelTypeSet& encrypted_types);
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // JsBackend implementation.
29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual void SetParentJsEventRouter(JsEventRouter* router);
29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual void RemoveParentJsEventRouter();
29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual const JsEventRouter* GetParentJsEventRouter() const;
29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual void ProcessMessage(const std::string& name, const JsArgList& args,
29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                const JsEventHandler* sender);
29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // JsEventRouter implementation.
29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual void RouteJsEvent(const std::string& event_name,
29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                              const JsArgList& args,
30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                              const JsEventHandler* dst);
30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct DoInitializeOptions {
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DoInitializeOptions(
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          const GURL& service_url,
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          sync_api::HttpPostProviderFactory* http_bridge_factory,
3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          const sync_api::SyncCredentials& credentials,
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bool delete_sync_data_folder,
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          const std::string& restored_key_for_bootstrapping,
30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          bool setup_for_test_mode);
31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ~DoInitializeOptions();
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL service_url;
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_api::HttpPostProviderFactory* http_bridge_factory;
3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      sync_api::SyncCredentials credentials;
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string lsid;
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool delete_sync_data_folder;
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      std::string restored_key_for_bootstrapping;
3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      bool setup_for_test_mode;
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    };
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Called on |frontend_loop_|.
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    void CreateSyncNotifier(const scoped_refptr<net::URLRequestContextGetter>&
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        request_context_getter);
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Note:
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The Do* methods are the various entry points from our SyncBackendHost.
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // It calls us on a dedicated thread to actually perform synchronous
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // (and potentially blocking) syncapi operations.
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on the SyncBackendHost core_thread_ to perform initialization
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // of the syncapi on behalf of SyncBackendHost::Initialize.
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoInitialize(const DoInitializeOptions& options);
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Called on our SyncBackendHost's core_thread_ to perform credential
3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // update on behalf of SyncBackendHost::UpdateCredentials
3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void DoUpdateCredentials(const sync_api::SyncCredentials& credentials);
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Called when the user disables or enables a sync type.
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    void DoUpdateEnabledTypes();
341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on the SyncBackendHost core_thread_ to tell the syncapi to start
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // syncing (generally after initialization and authentication).
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoStartSyncing();
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on the SyncBackendHost core_thread_ to nudge/pause/resume the
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // syncer.
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    void DoRequestNudge(const tracked_objects::Location& location);
3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void DoRequestClearServerData();
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Sets |deferred_nudge_for_cleanup_requested_| to true. See comment below.
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    void DeferNudgeForCleanup();
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on our SyncBackendHost's |core_thread_| to set the passphrase
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on behalf of SyncBackendHost::SupplyPassphrase.
3564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    void DoSetPassphrase(const std::string& passphrase, bool is_explicit);
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Getter/setter for whether we are waiting on SetPassphrase to process a
359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // passphrase. Set by SetPassphrase, cleared by OnPassphraseFailed or
360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // OnPassphraseAccepted.
361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    bool processing_passphrase() const;
362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    void set_processing_passphrase();
363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Called on SyncBackendHost's |core_thread_| to set the datatypes we need
365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // to encrypt as well as encrypt all local data of that type.
366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    void DoEncryptDataTypes(const syncable::ModelTypeSet& encrypted_types);
367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The shutdown order is a bit complicated:
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 1) From |core_thread_|, invoke the syncapi Shutdown call to do a final
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    SaveChanges, close sqlite handles, and halt the syncer thread (which
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    could potentially block for 1 minute).
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 2) Then, from |frontend_loop_|, halt the core_thread_. This causes
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    syncapi thread-exit handlers to run and make use of cached pointers to
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    various components owned implicitly by us.
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 3) Destroy this Core. That will delete syncapi components in a safe order
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    because the thread that was using them has exited (in step 2).
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoShutdown(bool stopping_sync);
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Posts a config request on the core thread.
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void DoRequestConfig(const syncable::ModelTypeBitSet& added_types);
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Start the configuration mode.
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void DoStartConfiguration(Callback0::Type* callback);
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Set the base request context to use when making HTTP calls.
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This method will add a reference to the context to persist it
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on the IO thread. Must be removed from IO thread.
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::SyncManager* syncapi() { return syncapi_.get(); }
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Delete the sync data folder to cleanup backend data.  Happens the first
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // time sync is enabled for a user (to prevent accidentally reusing old
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // sync databases), as well as shutdown when you're no longer syncing.
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DeleteSyncDataFolder();
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void ConnectChildJsEventRouter();
39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void DisconnectChildJsEventRouter();
39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void DoProcessMessage(
40172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        const std::string& name, const JsArgList& args,
40272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        const JsEventHandler* sender);
40372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // A callback from the SyncerThread when it is safe to continue config.
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    void FinishConfigureDataTypes();
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(UNIT_TEST)
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Special form of initialization that does not try and authenticate the
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // last known user (since it will fail in test mode) and does some extra
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // setup to nudge the syncapi into a usable state.
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoInitializeForTest(const std::wstring& test_user,
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             sync_api::HttpPostProviderFactory* factory,
4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             bool delete_sync_data_folder) {
4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Construct dummy credentials for test.
4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      sync_api::SyncCredentials credentials;
4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      credentials.email = WideToUTF8(test_user);
4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      credentials.sync_token = "token";
4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DoInitialize(DoInitializeOptions(GURL(), factory, credentials,
4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                       delete_sync_data_folder,
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       "", true));
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    friend class base::RefCountedThreadSafe<SyncBackendHost::Core>;
4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    friend class SyncBackendHostForProfileSyncTest;
4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual ~Core();
4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Return change processor for a particular model (return NULL on failure).
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ChangeProcessor* GetProcessor(syncable::ModelType modeltype);
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked when initialization of syncapi is complete and we can start
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // our timer.
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This must be called from the thread on which SaveChanges is intended to
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // be run on; the host's |core_thread_|.
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void StartSavingChanges();
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked periodically to tell the syncapi to persist its state
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // by writing to disk.
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This is called from the thread we were created on (which is the
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // SyncBackendHost |core_thread_|), using a repeating timer that is kicked
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // off as soon as the SyncManager tells us it completed
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // initialization.
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void SaveChanges();
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Dispatched to from HandleAuthErrorEventOnCoreLoop to handle updating
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // frontend UI components.
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleAuthErrorEventOnFrontendLoop(
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const GoogleServiceAuthError& new_auth_error);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
452201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Invoked when a passphrase is required to decrypt a set of Nigori keys,
453201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // or for encrypting.  If the reason is decryption, |for_decryption| will
454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // be true.
455201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    void NotifyPassphraseRequired(bool for_decryption);
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
457dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Invoked when the syncer attempts to set a passphrase but fails to decrypt
458dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // the cryptographer's pending keys. This tells the profile sync service
459dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // that a new passphrase is required.
460dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    void NotifyPassphraseFailed();
461dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked when the passphrase provided by the user has been accepted.
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void NotifyPassphraseAccepted(const std::string& bootstrap_token);
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Invoked when an updated token is available from the sync server.
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void NotifyUpdatedToken(const std::string& token);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
468dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Invoked when sync finishes encrypting new datatypes or has become aware
469dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // of new datatypes requiring encryption.
470dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    void NotifyEncryptionComplete(const syncable::ModelTypeSet&
471dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                      encrypted_types);
472dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called from Core::OnSyncCycleCompleted to handle updating frontend
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // thread components.
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleSyncCycleCompletedOnFrontendLoop(
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        sessions::SyncSessionSnapshot* snapshot);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleStopSyncingPermanentlyOnFrontendLoop();
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Called to handle success/failure of clearing server data
4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void HandleClearServerDataSucceededOnFrontendLoop();
4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    void HandleClearServerDataFailedOnFrontendLoop();
4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called from Core::OnInitializationComplete to handle updating
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // frontend thread components.
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleInitalizationCompletedOnFrontendLoop();
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void RouteJsEventOnFrontendLoop(
48972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        const std::string& name, const JsArgList& args,
49072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        const JsEventHandler* dst);
49172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    void FinishConfigureDataTypesOnFrontendLoop();
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Return true if a model lives on the current thread.
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool IsCurrentThreadSafeForModel(syncable::ModelType model_type);
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Our parent SyncBackendHost
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SyncBackendHost* host_;
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The timer used to periodically call SaveChanges.
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::RepeatingTimer<Core> save_changes_timer_;
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The top-level syncapi entry point.
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<sync_api::SyncManager> syncapi_;
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<sync_notifier::SyncNotifier> sync_notifier_;
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    JsSyncManagerObserver sync_manager_observer_;
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    JsEventRouter* parent_router_;
51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
512dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Denotes if the core is currently attempting to set a passphrase. While
513dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // this is true, OnPassphraseRequired calls are dropped.
514dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Note: after initialization, this variable should only ever be accessed or
515dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // modified from within the frontend_loop_ (UI thread).
516dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    bool processing_passphrase_;
517dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // True when a datatype has been disabled so that we nudge once sync is
519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // resumed (after configuration is finished).
520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool deferred_nudge_for_cleanup_requested_;
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Core);
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // InitializationComplete passes through the SyncBackendHost to forward
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // on to |frontend_|, and so that tests can intercept here if they need to
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // set up initial conditions.
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void HandleInitializationCompletedOnFrontendLoop();
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Posts a nudge request on the core thread.
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void RequestNudge(const tracked_objects::Location& location);
5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Called to finish the job of ConfigureDataTypes once the syncer is in
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // configuration mode.
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void FinishConfigureDataTypes();
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void FinishConfigureDataTypesOnFrontendLoop();
537dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Allows tests to perform alternate core initialization work.
5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void InitCore(const Core::DoInitializeOptions& options);
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Factory method for HttpPostProviderFactories.
5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory(
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::URLRequestContextGetter* getter);
5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop* core_loop() { return core_thread_.message_loop(); }
5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void set_syncapi_initialized() { syncapi_initialized_ = true; }
5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Helpers to persist a token that can be used to bootstrap sync encryption
5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // across browser restart to avoid requiring the user to re-enter their
5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // passphrase.  |token| must be valid UTF-8 as we use the PrefService for
5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // storage.
5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void PersistEncryptionBootstrapToken(const std::string& token);
5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string RestoreEncryptionBootstrapToken();
5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Our core, which communicates directly to the syncapi.
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<Core> core_;
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FRIEND_TEST_ALL_PREFIXES(SyncBackendHostTest, MakePendingConfigModeState);
561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  struct PendingConfigureDataTypesState {
563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingConfigureDataTypesState();
564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ~PendingConfigureDataTypesState();
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // A task that should be called once data type configuration is
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // complete.
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<CancelableTask> ready_task;
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The set of types that we are waiting to be initially synced in a
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // configuration cycle.
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncable::ModelTypeSet initial_types;
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Additional details about which types were added / removed.
575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool deleted_type;
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncable::ModelTypeBitSet added_types;
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UIModelWorker* ui_worker();
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void ConfigureAutofillMigration();
58221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Helper function for ConfigureDataTypes().  Caller owns return
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // value.  Takes ownership of |ready_task| (but not |routing_info|).
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static PendingConfigureDataTypesState* MakePendingConfigModeState(
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const DataTypeController::TypeMap& data_type_controllers,
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const syncable::ModelTypeSet& types,
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      CancelableTask* ready_task,
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ModelSafeRoutingInfo* routing_info);
590dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A thread we dedicate for use by our Core to perform initialization,
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // authentication, handle messages from the syncapi, and periodically tell
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the syncapi to persist itself.
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Thread core_thread_;
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A reference to the MessageLoop used to construct |this|, so we know how
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to safely talk back to the SyncFrontend.
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop* const frontend_loop_;
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Profile* profile_;
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is state required to implement ModelSafeWorkerRegistrar.
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct {
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We maintain ownership of all workers.  In some cases, we need to ensure
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // shutdown occurs in an expected sequence by Stop()ing certain workers.
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // They are guaranteed to be valid because we only destroy elements of
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // |workers_| after the syncapi has been destroyed.  Unless a worker is no
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // longer needed because all types that get routed to it have been disabled
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // (from syncing). In that case, we'll destroy on demand *after* routing
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // any dependent types to GROUP_PASSIVE, so that the syncapi doesn't call
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // into garbage.  If a key is present, it means at least one ModelType that
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // routes to that model safe group is being synced.
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WorkerMap workers;
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_sync::ModelSafeRoutingInfo routing_info;
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } registrar_;
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The user can incur changes to registrar_ at any time from the UI thread.
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The syncapi needs to periodically get a consistent snapshot of the state,
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and it does so from a different thread.  Therefore, we protect creation,
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // destruction, and re-routing events by acquiring this lock.  Note that the
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SyncBackendHost may read (on the UI thread or core thread) from registrar_
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // without acquiring the lock (which is typically "read ModelSafeWorker
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pointer value", and then invoke methods), because lifetimes are managed on
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the UI thread.  Of course, this comment only applies to ModelSafeWorker
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // impls that are themselves thread-safe, such as UIModelWorker.
62672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  mutable base::Lock registrar_lock_;
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The frontend which we serve (and are owned by).
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncFrontend* frontend_;
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The change processors that handle the different data types.
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<syncable::ModelType, ChangeProcessor*> processors_;
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Path of the folder that stores the sync data files.
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath sync_data_folder_path_;
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<PendingConfigureDataTypesState> pending_download_state_;
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<PendingConfigureDataTypesState> pending_config_mode_state_;
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UI-thread cache of the last AuthErrorState received from syncapi.
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GoogleServiceAuthError last_auth_error_;
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UI-thread cache of the last SyncSessionSnapshot received from syncapi.
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<sessions::SyncSessionSnapshot> last_snapshot_;
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Whether we've processed the initialization complete callback.
6473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool syncapi_initialized_;
6483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser_sync
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
655