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