sync_backend_host.h revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 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_
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/lock.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/ref_counted.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/thread.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/google_service_auth_error.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/notification_method.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncapi.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/model_safe_worker.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/data_type_controller.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/ui_model_worker.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/model_type.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_request_context_getter.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CancelableTask;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass Profile;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace sessions {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SyncSessionSnapshot;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ChangeProcessor;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DataTypeController;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SyncFrontend is the interface used by SyncBackendHost to communicate with
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the entity that created it and, presumably, is interested in sync-related
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// activity.
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NOTE: All methods will be invoked by a SyncBackendHost on the same thread
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// used to create that SyncBackendHost.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SyncFrontend {
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncFrontend() {}
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend has completed initialization and it is now ready to accept and
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // process changes.
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnBackendInitialized() = 0;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend queried the server recently and received some updates.
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnSyncCycleCompleted() = 0;
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend encountered an authentication problem and requests new
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // credentials to be provided. See SyncBackendHost::Authenticate for details.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnAuthError() = 0;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We are no longer permitted to communicate with the server. Sync should
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be disabled and state cleaned up at once.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnStopSyncingPermanently() = 0;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't delete through SyncFrontend interface.
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~SyncFrontend() {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncFrontend);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A UI-thread safe API into the sync backend that "hosts" the top-level
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// syncapi element, the SyncManager, on its own thread. This class handles
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// dispatch of potentially blocking calls to appropriate threads and ensures
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that the SyncFrontend is only accessed on the UI loop.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef sync_api::UserShare* UserShareHandle;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef sync_api::SyncManager::Status::Summary StatusSummary;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef sync_api::SyncManager::Status Status;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::map<ModelSafeGroup,
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   scoped_refptr<browser_sync::ModelSafeWorker> > WorkerMap;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a SyncBackendHost with a reference to the |frontend| that it serves
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and communicates to via the SyncFrontend interface (on the same thread
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it used to call the constructor).
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncBackendHost(SyncFrontend* frontend,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  Profile* profile,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  const FilePath& profile_path,
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  const DataTypeController::TypeMap& data_type_controllers);
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For testing.
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(skrul): Extract an interface so this is not needed.
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncBackendHost();
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~SyncBackendHost();
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to kick off asynchronous initialization.
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // As a fallback when no cached auth information is available, try to
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bootstrap authentication using |lsid|, if it isn't empty.
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Optionally delete the Sync Data folder (if it's corrupt).
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Initialize(const GURL& service_url,
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  const syncable::ModelTypeSet& types,
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  URLRequestContextGetter* baseline_context_getter,
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  const std::string& lsid,
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  bool delete_sync_data_folder,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  bool invalidate_sync_login,
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  bool invalidate_sync_xmpp_login,
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  bool use_chrome_async_socket,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  NotificationMethod notification_method);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to kick off asynchronous authentication.
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Authenticate(const std::string& username, const std::string& password,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    const std::string& captcha);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This starts the SyncerThread running a Syncer object to communicate with
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sync servers.  Until this is called, no changes will leave or enter this
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // browser from the cloud / sync servers.
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_|.
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void StartSyncingWithServer();
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to asynchronously set the passphrase.
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetPassphrase(const std::string& passphrase);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to kick off shutdown.
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |sync_disabled| indicates if syncing is being disabled or not.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // See the implementation and Core::DoShutdown for details.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Shutdown(bool sync_disabled);
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Changes the set of data types that are currently being synced.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The ready_task will be run when all of the requested data types
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are up-to-date and ready for activation.  The task will cancelled
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // upon shutdown.  The method takes ownership of the task pointer.
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ConfigureDataTypes(const syncable::ModelTypeSet& types,
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  CancelableTask* ready_task);
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Activates change processing for the given data type.  This must
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be called synchronously with the data type's model association so
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // no changes are dropped between model association and change
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // processor activation.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ActivateDataType(DataTypeController* data_type_controller,
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        ChangeProcessor* change_processor);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Deactivates change processing for the given data type.
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void DeactivateDataType(DataTypeController* data_type_controller,
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          ChangeProcessor* change_processor);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Requests the backend to pause.  Returns true if the request is
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sent sucessfully.  When the backend does pause, a SYNC_PAUSED
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification is sent to the notification service.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool RequestPause();
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Requests the backend to resume.  Returns true if the request is
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sent sucessfully.  When the backend does resume, a SYNC_RESUMED
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification is sent to the notification service.
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool RequestResume();
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called on |frontend_loop_| to obtain a handle to the UserShare needed
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for creating transactions.
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserShareHandle GetUserShareHandle() const;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called from any thread to obtain current status information in detailed or
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // summarized form.
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Status GetDetailedStatus();
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatusSummary GetStatusSummary();
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GoogleServiceAuthError& GetAuthError() const;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const sessions::SyncSessionSnapshot* GetLastSessionSnapshot() const;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath& sync_data_folder_path() const {
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return sync_data_folder_path_;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the authenticated username of the sync user, or empty if none
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // exists. It will only exist if the authentication service provider (e.g
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // GAIA) has confirmed the username is authentic.
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 GetAuthenticatedUsername() const;
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ModelSafeWorkerRegistrar implementation.
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetWorkers(std::vector<browser_sync::ModelSafeWorker*>* out);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out);
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(UNIT_TEST)
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called from unit test to bypass authentication and initialize the syncapi
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to a state suitable for testing but not production.
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InitializeForTestMode(const std::wstring& test_user,
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             sync_api::HttpPostProviderFactory* factory,
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             sync_api::HttpPostProviderFactory* auth_factory,
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool delete_sync_data_folder,
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             NotificationMethod notification_method) {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!core_thread_.Start())
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.workers[GROUP_UI] = new UIModelWorker(frontend_loop_);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE;
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::PREFERENCES] = GROUP_PASSIVE;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::AUTOFILL] = GROUP_PASSIVE;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::THEMES] = GROUP_PASSIVE;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::TYPED_URLS] = GROUP_PASSIVE;
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::NIGORI] = GROUP_PASSIVE;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[syncable::PASSWORDS] = GROUP_PASSIVE;
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    core_thread_.message_loop()->PostTask(FROM_HERE,
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(core_.get(),
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &SyncBackendHost::Core::DoInitializeForTest,
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        test_user,
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        factory,
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        auth_factory,
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        delete_sync_data_folder,
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        notification_method));
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // InitializationComplete passes through the SyncBackendHost to forward
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on to |frontend_|, and so that tests can intercept here if they need to
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // set up initial conditions.
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void HandleInitializationCompletedOnFrontendLoop();
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The real guts of SyncBackendHost, to keep the public client API clean.
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Core : public base::RefCountedThreadSafe<SyncBackendHost::Core>,
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               public sync_api::SyncManager::Observer {
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    explicit Core(SyncBackendHost* backend);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // SyncManager::Observer implementation.  The Core just acts like an air
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // traffic controller here, forwarding incoming messages to appropriate
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // landing threads.
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnChangesApplied(
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        syncable::ModelType model_type,
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const sync_api::BaseTransaction* trans,
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const sync_api::SyncManager::ChangeRecord* changes,
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        int change_count);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnSyncCycleCompleted(
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const sessions::SyncSessionSnapshot* snapshot);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnInitializationComplete();
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnAuthError(const GoogleServiceAuthError& auth_error);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnPassphraseRequired();
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnPassphraseAccepted();
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnPaused();
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnResumed();
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void OnStopSyncingPermanently();
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct DoInitializeOptions {
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DoInitializeOptions(
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          const GURL& service_url,
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bool attempt_last_user_authentication,
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          sync_api::HttpPostProviderFactory* http_bridge_factory,
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          sync_api::HttpPostProviderFactory* auth_http_bridge_factory,
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          const std::string& lsid,
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bool delete_sync_data_folder,
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bool invalidate_sync_login,
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bool invalidate_sync_xmpp_login,
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bool use_chrome_async_socket,
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          NotificationMethod notification_method)
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          : service_url(service_url),
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            attempt_last_user_authentication(attempt_last_user_authentication),
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            http_bridge_factory(http_bridge_factory),
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            auth_http_bridge_factory(auth_http_bridge_factory),
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            lsid(lsid),
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            delete_sync_data_folder(delete_sync_data_folder),
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            invalidate_sync_login(invalidate_sync_login),
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            invalidate_sync_xmpp_login(invalidate_sync_xmpp_login),
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            use_chrome_async_socket(use_chrome_async_socket),
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            notification_method(notification_method) {}
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL service_url;
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool attempt_last_user_authentication;
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_api::HttpPostProviderFactory* http_bridge_factory;
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_api::HttpPostProviderFactory* auth_http_bridge_factory;
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string lsid;
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool delete_sync_data_folder;
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool invalidate_sync_login;
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool invalidate_sync_xmpp_login;
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool use_chrome_async_socket;
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationMethod notification_method;
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    };
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Note:
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The Do* methods are the various entry points from our SyncBackendHost.
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // It calls us on a dedicated thread to actually perform synchronous
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // (and potentially blocking) syncapi operations.
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on the SyncBackendHost core_thread_ to perform initialization
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // of the syncapi on behalf of SyncBackendHost::Initialize.
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoInitialize(const DoInitializeOptions& options);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on our SyncBackendHost's core_thread_ to perform authentication
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on behalf of SyncBackendHost::Authenticate.
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoAuthenticate(const std::string& username,
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        const std::string& password,
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        const std::string& captcha);
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on the SyncBackendHost core_thread_ to tell the syncapi to start
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // syncing (generally after initialization and authentication).
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoStartSyncing();
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on the SyncBackendHost core_thread_ to nudge/pause/resume the
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // syncer.
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoRequestNudge();
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoRequestPause();
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoRequestResume();
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called on our SyncBackendHost's |core_thread_| to set the passphrase
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on behalf of SyncBackendHost::SupplyPassphrase.
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoSetPassphrase(const std::string& passphrase);
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The shutdown order is a bit complicated:
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 1) From |core_thread_|, invoke the syncapi Shutdown call to do a final
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    SaveChanges, close sqlite handles, and halt the syncer thread (which
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    could potentially block for 1 minute).
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 2) Then, from |frontend_loop_|, halt the core_thread_. This causes
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    syncapi thread-exit handlers to run and make use of cached pointers to
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    various components owned implicitly by us.
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 3) Destroy this Core. That will delete syncapi components in a safe order
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    because the thread that was using them has exited (in step 2).
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoShutdown(bool stopping_sync);
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Set the base request context to use when making HTTP calls.
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This method will add a reference to the context to persist it
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on the IO thread. Must be removed from IO thread.
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::SyncManager* syncapi() { return syncapi_.get(); }
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Delete the sync data folder to cleanup backend data.  Happens the first
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // time sync is enabled for a user (to prevent accidentally reusing old
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // sync databases), as well as shutdown when you're no longer syncing.
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DeleteSyncDataFolder();
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(UNIT_TEST)
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Special form of initialization that does not try and authenticate the
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // last known user (since it will fail in test mode) and does some extra
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // setup to nudge the syncapi into a useable state.
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void DoInitializeForTest(const std::wstring& test_user,
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             sync_api::HttpPostProviderFactory* factory,
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             sync_api::HttpPostProviderFactory* auth_factory,
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool delete_sync_data_folder,
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             NotificationMethod notification_method) {
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DoInitialize(DoInitializeOptions(GURL(), false, factory, auth_factory,
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       std::string(), delete_sync_data_folder,
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       false, false, false,
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       notification_method));
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        syncapi_->SetupForTestMode(test_user);
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    friend class base::RefCountedThreadSafe<SyncBackendHost::Core>;
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ~Core() {}
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Sends a SYNC_PAUSED notification to the notification service on
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the UI thread.
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void NotifyPaused();
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Sends a SYNC_RESUMED notification to the notification service
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // on the UI thread.
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void NotifyResumed();
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked when initialization of syncapi is complete and we can start
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // our timer.
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This must be called from the thread on which SaveChanges is intended to
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // be run on; the host's |core_thread_|.
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void StartSavingChanges();
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked periodically to tell the syncapi to persist its state
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // by writing to disk.
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This is called from the thread we were created on (which is the
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // SyncBackendHost |core_thread_|), using a repeating timer that is kicked
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // off as soon as the SyncManager tells us it completed
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // initialization.
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void SaveChanges();
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Dispatched to from HandleAuthErrorEventOnCoreLoop to handle updating
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // frontend UI components.
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleAuthErrorEventOnFrontendLoop(
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const GoogleServiceAuthError& new_auth_error);
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked when a passphrase is required to decrypt a set of Nigori keys.
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void NotifyPassphraseRequired();
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Invoked when the passphrase provided by the user has been accepted.
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void NotifyPassphraseAccepted();
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called from Core::OnSyncCycleCompleted to handle updating frontend
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // thread components.
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleSyncCycleCompletedOnFrontendLoop(
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        sessions::SyncSessionSnapshot* snapshot);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleStopSyncingPermanentlyOnFrontendLoop();
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called from Core::OnInitializationComplete to handle updating
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // frontend thread components.
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void HandleInitalizationCompletedOnFrontendLoop();
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Return true if a model lives on the current thread.
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool IsCurrentThreadSafeForModel(syncable::ModelType model_type);
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Our parent SyncBackendHost
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SyncBackendHost* host_;
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The timer used to periodically call SaveChanges.
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::RepeatingTimer<Core> save_changes_timer_;
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The top-level syncapi entry point.
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<sync_api::SyncManager> syncapi_;
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Core);
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Our core, which communicates directly to the syncapi.
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<Core> core_;
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UIModelWorker* ui_worker();
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A thread we dedicate for use by our Core to perform initialization,
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // authentication, handle messages from the syncapi, and periodically tell
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the syncapi to persist itself.
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Thread core_thread_;
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A reference to the MessageLoop used to construct |this|, so we know how
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to safely talk back to the SyncFrontend.
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop* const frontend_loop_;
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Profile* profile_;
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is state required to implement ModelSafeWorkerRegistrar.
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct {
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We maintain ownership of all workers.  In some cases, we need to ensure
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // shutdown occurs in an expected sequence by Stop()ing certain workers.
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // They are guaranteed to be valid because we only destroy elements of
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // |workers_| after the syncapi has been destroyed.  Unless a worker is no
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // longer needed because all types that get routed to it have been disabled
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // (from syncing). In that case, we'll destroy on demand *after* routing
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // any dependent types to GROUP_PASSIVE, so that the syncapi doesn't call
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // into garbage.  If a key is present, it means at least one ModelType that
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // routes to that model safe group is being synced.
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WorkerMap workers;
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_sync::ModelSafeRoutingInfo routing_info;
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } registrar_;
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The user can incur changes to registrar_ at any time from the UI thread.
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The syncapi needs to periodically get a consistent snapshot of the state,
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and it does so from a different thread.  Therefore, we protect creation,
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // destruction, and re-routing events by acquiring this lock.  Note that the
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SyncBackendHost may read (on the UI thread or core thread) from registrar_
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // without acquiring the lock (which is typically "read ModelSafeWorker
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pointer value", and then invoke methods), because lifetimes are managed on
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the UI thread.  Of course, this comment only applies to ModelSafeWorker
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // impls that are themselves thread-safe, such as UIModelWorker.
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Lock registrar_lock_;
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The frontend which we serve (and are owned by).
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncFrontend* frontend_;
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The change processors that handle the different data types.
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<syncable::ModelType, ChangeProcessor*> processors_;
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Path of the folder that stores the sync data files.
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath sync_data_folder_path_;
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // List of registered data type controllers.
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DataTypeController::TypeMap data_type_controllers_;
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A task that should be called once data type configuration is
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // complete.
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<CancelableTask> configure_ready_task_;
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The set of types that we are waiting to be initially synced in a
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // configuration cycle.
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::ModelTypeSet configure_initial_sync_types_;
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UI-thread cache of the last AuthErrorState received from syncapi.
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GoogleServiceAuthError last_auth_error_;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UI-thread cache of the last SyncSessionSnapshot received from syncapi.
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<sessions::SyncSessionSnapshot> last_snapshot_;
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser_sync
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
484