Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/sync/glue/sync_backend_host.h"
      6 
      7 #include <algorithm>
      8 #include <map>
      9 
     10 #include "base/bind.h"
     11 #include "base/command_line.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/file_util.h"
     14 #include "base/files/file_path.h"
     15 #include "base/location.h"
     16 #include "base/metrics/histogram.h"
     17 #include "base/strings/utf_string_conversions.h"
     18 #include "base/threading/thread_restrictions.h"
     19 #include "base/timer/timer.h"
     20 #include "base/tracked_objects.h"
     21 #include "build/build_config.h"
     22 #include "chrome/browser/invalidation/invalidation_service.h"
     23 #include "chrome/browser/invalidation/invalidation_service_factory.h"
     24 #include "chrome/browser/chrome_notification_types.h"
     25 #include "chrome/browser/net/network_time_tracker.h"
     26 #include "chrome/browser/profiles/profile.h"
     27 #include "chrome/browser/signin/token_service.h"
     28 #include "chrome/browser/signin/token_service_factory.h"
     29 #include "chrome/browser/sync/glue/change_processor.h"
     30 #include "chrome/browser/sync/glue/chrome_encryptor.h"
     31 #include "chrome/browser/sync/glue/device_info.h"
     32 #include "chrome/browser/sync/glue/sync_backend_registrar.h"
     33 #include "chrome/browser/sync/glue/synced_device_tracker.h"
     34 #include "chrome/browser/sync/sync_prefs.h"
     35 #include "chrome/common/chrome_switches.h"
     36 #include "chrome/common/chrome_version_info.h"
     37 #include "content/public/browser/browser_thread.h"
     38 #include "content/public/browser/notification_details.h"
     39 #include "content/public/browser/notification_service.h"
     40 #include "content/public/browser/notification_source.h"
     41 #include "content/public/common/content_client.h"
     42 #include "google_apis/gaia/gaia_constants.h"
     43 #include "jingle/notifier/base/notification_method.h"
     44 #include "jingle/notifier/base/notifier_options.h"
     45 #include "net/base/host_port_pair.h"
     46 #include "net/url_request/url_request_context_getter.h"
     47 #include "sync/internal_api/public/base_transaction.h"
     48 #include "sync/internal_api/public/engine/model_safe_worker.h"
     49 #include "sync/internal_api/public/http_bridge.h"
     50 #include "sync/internal_api/public/internal_components_factory_impl.h"
     51 #include "sync/internal_api/public/read_transaction.h"
     52 #include "sync/internal_api/public/sync_manager_factory.h"
     53 #include "sync/internal_api/public/util/experiments.h"
     54 #include "sync/internal_api/public/util/sync_string_conversions.h"
     55 #include "sync/protocol/encryption.pb.h"
     56 #include "sync/protocol/sync.pb.h"
     57 #include "sync/util/nigori.h"
     58 
     59 static const int kSaveChangesIntervalSeconds = 10;
     60 static const base::FilePath::CharType kSyncDataFolderName[] =
     61     FILE_PATH_LITERAL("Sync Data");
     62 
     63 typedef TokenService::TokenAvailableDetails TokenAvailableDetails;
     64 
     65 typedef GoogleServiceAuthError AuthError;
     66 
     67 namespace browser_sync {
     68 
     69 using content::BrowserThread;
     70 using syncer::InternalComponentsFactory;
     71 using syncer::InternalComponentsFactoryImpl;
     72 using syncer::sessions::SyncSessionSnapshot;
     73 using syncer::SyncCredentials;
     74 
     75 namespace {
     76 
     77 // Helper struct to handle currying params to
     78 // SyncBackendHost::Core::DoConfigureSyncer.
     79 struct DoConfigureSyncerTypes {
     80   DoConfigureSyncerTypes() {}
     81   ~DoConfigureSyncerTypes() {}
     82   syncer::ModelTypeSet to_download;
     83   syncer::ModelTypeSet to_purge;
     84   syncer::ModelTypeSet to_journal;
     85   syncer::ModelTypeSet to_unapply;
     86 };
     87 
     88 }  // namespace
     89 
     90 // Helper macros to log with the syncer thread name; useful when there
     91 // are multiple syncers involved.
     92 
     93 #define SLOG(severity) LOG(severity) << name_ << ": "
     94 
     95 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": "
     96 
     97 class SyncBackendHost::Core
     98     : public base::RefCountedThreadSafe<SyncBackendHost::Core>,
     99       public syncer::SyncEncryptionHandler::Observer,
    100       public syncer::SyncManager::Observer {
    101  public:
    102   Core(const std::string& name,
    103        const base::FilePath& sync_data_folder_path,
    104        const base::WeakPtr<SyncBackendHost>& backend);
    105 
    106   // SyncManager::Observer implementation.  The Core just acts like an air
    107   // traffic controller here, forwarding incoming messages to appropriate
    108   // landing threads.
    109   virtual void OnSyncCycleCompleted(
    110       const syncer::sessions::SyncSessionSnapshot& snapshot) OVERRIDE;
    111   virtual void OnInitializationComplete(
    112       const syncer::WeakHandle<syncer::JsBackend>& js_backend,
    113       const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
    114           debug_info_listener,
    115       bool success,
    116       syncer::ModelTypeSet restored_types) OVERRIDE;
    117   virtual void OnConnectionStatusChange(
    118       syncer::ConnectionStatus status) OVERRIDE;
    119   virtual void OnStopSyncingPermanently() OVERRIDE;
    120   virtual void OnUpdatedToken(const std::string& token) OVERRIDE;
    121   virtual void OnActionableError(
    122       const syncer::SyncProtocolError& sync_error) OVERRIDE;
    123 
    124   // SyncEncryptionHandler::Observer implementation.
    125   virtual void OnPassphraseRequired(
    126       syncer::PassphraseRequiredReason reason,
    127       const sync_pb::EncryptedData& pending_keys) OVERRIDE;
    128   virtual void OnPassphraseAccepted() OVERRIDE;
    129   virtual void OnBootstrapTokenUpdated(
    130       const std::string& bootstrap_token,
    131       syncer::BootstrapTokenType type) OVERRIDE;
    132   virtual void OnEncryptedTypesChanged(
    133       syncer::ModelTypeSet encrypted_types,
    134       bool encrypt_everything) OVERRIDE;
    135   virtual void OnEncryptionComplete() OVERRIDE;
    136   virtual void OnCryptographerStateChanged(
    137       syncer::Cryptographer* cryptographer) OVERRIDE;
    138   virtual void OnPassphraseTypeChanged(syncer::PassphraseType type,
    139                                        base::Time passphrase_time) OVERRIDE;
    140 
    141   // Forwards an invalidation state change to the sync manager.
    142   void DoOnInvalidatorStateChange(syncer::InvalidatorState state);
    143 
    144   // Forwards an invalidation to the sync manager.
    145   void DoOnIncomingInvalidation(
    146       syncer::ObjectIdInvalidationMap invalidation_map);
    147 
    148   // Note:
    149   //
    150   // The Do* methods are the various entry points from our
    151   // SyncBackendHost.  They are all called on the sync thread to
    152   // actually perform synchronous (and potentially blocking) syncapi
    153   // operations.
    154   //
    155   // Called to perform initialization of the syncapi on behalf of
    156   // SyncBackendHost::Initialize.
    157   void DoInitialize(scoped_ptr<DoInitializeOptions> options);
    158 
    159   // Called to perform credential update on behalf of
    160   // SyncBackendHost::UpdateCredentials.
    161   void DoUpdateCredentials(const syncer::SyncCredentials& credentials);
    162 
    163   // Called to tell the syncapi to start syncing (generally after
    164   // initialization and authentication).
    165   void DoStartSyncing(const syncer::ModelSafeRoutingInfo& routing_info);
    166 
    167   // Called to set the passphrase for encryption.
    168   void DoSetEncryptionPassphrase(const std::string& passphrase,
    169                                  bool is_explicit);
    170 
    171   // Called to decrypt the pending keys.
    172   void DoSetDecryptionPassphrase(const std::string& passphrase);
    173 
    174   // Called to turn on encryption of all sync data as well as
    175   // reencrypt everything.
    176   void DoEnableEncryptEverything();
    177 
    178   // Called at startup to download the control types. Will invoke
    179   // DoInitialProcessControlTypes on success, and OnControlTypesDownloadRetry
    180   // if an error occurred.
    181   void DoDownloadControlTypes(syncer::ConfigureReason reason);
    182 
    183   // Ask the syncer to check for updates for the specified types.
    184   void DoRefreshTypes(syncer::ModelTypeSet types);
    185 
    186   // Invoked if we failed to download the necessary control types at startup.
    187   // Invokes SyncBackendHost::HandleControlTypesDownloadRetry.
    188   void OnControlTypesDownloadRetry();
    189 
    190   // Called to perform tasks which require the control data to be downloaded.
    191   // This includes refreshing encryption, setting up the device info change
    192   // processor, etc.
    193   void DoInitialProcessControlTypes();
    194 
    195   // Some parts of DoInitialProcessControlTypes() may be executed on a different
    196   // thread.  This function asynchronously continues the work started in
    197   // DoInitialProcessControlTypes() once that other thread gets back to us.
    198   void DoFinishInitialProcessControlTypes();
    199 
    200   // The shutdown order is a bit complicated:
    201   // 1) Call DoStopSyncManagerForShutdown() from |frontend_loop_| to request
    202   //    sync manager to stop as soon as possible.
    203   // 2) Post DoShutdown() to sync loop to clean up backend state, save
    204   //    directory and destroy sync manager.
    205   void DoStopSyncManagerForShutdown();
    206   void DoShutdown(bool sync_disabled);
    207   void DoDestroySyncManager();
    208 
    209   // Configuration methods that must execute on sync loop.
    210   void DoConfigureSyncer(
    211       syncer::ConfigureReason reason,
    212       const DoConfigureSyncerTypes& config_types,
    213       const syncer::ModelSafeRoutingInfo routing_info,
    214       const base::Callback<void(syncer::ModelTypeSet,
    215                                 syncer::ModelTypeSet)>& ready_task,
    216       const base::Closure& retry_callback);
    217   void DoFinishConfigureDataTypes(
    218       syncer::ModelTypeSet types_to_config,
    219       const base::Callback<void(syncer::ModelTypeSet,
    220                                 syncer::ModelTypeSet)>& ready_task);
    221   void DoRetryConfiguration(
    222       const base::Closure& retry_callback);
    223 
    224   // Set the base request context to use when making HTTP calls.
    225   // This method will add a reference to the context to persist it
    226   // on the IO thread. Must be removed from IO thread.
    227 
    228   syncer::SyncManager* sync_manager() { return sync_manager_.get(); }
    229 
    230   SyncedDeviceTracker* synced_device_tracker() {
    231     return synced_device_tracker_.get();
    232   }
    233 
    234   // Delete the sync data folder to cleanup backend data.  Happens the first
    235   // time sync is enabled for a user (to prevent accidentally reusing old
    236   // sync databases), as well as shutdown when you're no longer syncing.
    237   void DeleteSyncDataFolder();
    238 
    239  private:
    240   friend class base::RefCountedThreadSafe<SyncBackendHost::Core>;
    241   friend class SyncBackendHostForProfileSyncTest;
    242 
    243   virtual ~Core();
    244 
    245   // Invoked when initialization of syncapi is complete and we can start
    246   // our timer.
    247   // This must be called from the thread on which SaveChanges is intended to
    248   // be run on; the host's |registrar_->sync_thread()|.
    249   void StartSavingChanges();
    250 
    251   // Invoked periodically to tell the syncapi to persist its state
    252   // by writing to disk.
    253   // This is called from the thread we were created on (which is sync thread),
    254   // using a repeating timer that is kicked off as soon as the SyncManager
    255   // tells us it completed initialization.
    256   void SaveChanges();
    257 
    258   // Name used for debugging.
    259   const std::string name_;
    260 
    261   // Path of the folder that stores the sync data files.
    262   const base::FilePath sync_data_folder_path_;
    263 
    264   // Our parent SyncBackendHost.
    265   syncer::WeakHandle<SyncBackendHost> host_;
    266 
    267   // The loop where all the sync backend operations happen.
    268   // Non-NULL only between calls to DoInitialize() and ~Core().
    269   base::MessageLoop* sync_loop_;
    270 
    271   // Our parent's registrar (not owned).  Non-NULL only between
    272   // calls to DoInitialize() and DoShutdown().
    273   SyncBackendRegistrar* registrar_;
    274 
    275   // The timer used to periodically call SaveChanges.
    276   scoped_ptr<base::RepeatingTimer<Core> > save_changes_timer_;
    277 
    278   // Our encryptor, which uses Chrome's encryption functions.
    279   ChromeEncryptor encryptor_;
    280 
    281   // A special ChangeProcessor that tracks the DEVICE_INFO type for us.
    282   scoped_ptr<SyncedDeviceTracker> synced_device_tracker_;
    283 
    284   // The top-level syncapi entry point.  Lives on the sync thread.
    285   scoped_ptr<syncer::SyncManager> sync_manager_;
    286 
    287   base::WeakPtrFactory<Core> weak_ptr_factory_;
    288 
    289   DISALLOW_COPY_AND_ASSIGN(Core);
    290 };
    291 
    292 SyncBackendHost::SyncBackendHost(
    293     const std::string& name,
    294     Profile* profile,
    295     const base::WeakPtr<SyncPrefs>& sync_prefs)
    296     : weak_ptr_factory_(this),
    297       frontend_loop_(base::MessageLoop::current()),
    298       profile_(profile),
    299       name_(name),
    300       core_(new Core(name_, profile_->GetPath().Append(kSyncDataFolderName),
    301                      weak_ptr_factory_.GetWeakPtr())),
    302       initialization_state_(NOT_ATTEMPTED),
    303       sync_prefs_(sync_prefs),
    304       frontend_(NULL),
    305       cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
    306       invalidator_(
    307           invalidation::InvalidationServiceFactory::GetForProfile(profile)),
    308       invalidation_handler_registered_(false) {
    309 }
    310 
    311 SyncBackendHost::SyncBackendHost(Profile* profile)
    312     : weak_ptr_factory_(this),
    313       frontend_loop_(base::MessageLoop::current()),
    314       profile_(profile),
    315       name_("Unknown"),
    316       initialization_state_(NOT_ATTEMPTED),
    317       frontend_(NULL),
    318       cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
    319       invalidation_handler_registered_(false) {
    320 }
    321 
    322 SyncBackendHost::~SyncBackendHost() {
    323   DCHECK(!core_.get() && !frontend_) << "Must call Shutdown before destructor.";
    324   DCHECK(!registrar_.get());
    325 }
    326 
    327 namespace {
    328 
    329 scoped_ptr<syncer::HttpPostProviderFactory> MakeHttpBridgeFactory(
    330     const scoped_refptr<net::URLRequestContextGetter>& getter,
    331     const NetworkTimeTracker::UpdateCallback& update_callback) {
    332   chrome::VersionInfo version_info;
    333   return scoped_ptr<syncer::HttpPostProviderFactory>(
    334       new syncer::HttpBridgeFactory(
    335           getter.get(),
    336           DeviceInfo::MakeUserAgentForSyncApi(version_info),
    337           update_callback));
    338 }
    339 
    340 }  // namespace
    341 
    342 void SyncBackendHost::Initialize(
    343     SyncFrontend* frontend,
    344     scoped_ptr<base::Thread> sync_thread,
    345     const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
    346     const GURL& sync_service_url,
    347     const SyncCredentials& credentials,
    348     bool delete_sync_data_folder,
    349     scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
    350     scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
    351     syncer::ReportUnrecoverableErrorFunction
    352         report_unrecoverable_error_function) {
    353   registrar_.reset(new SyncBackendRegistrar(name_,
    354                                             profile_,
    355                                             sync_thread.Pass()));
    356   CHECK(registrar_->sync_thread());
    357 
    358   frontend_ = frontend;
    359   DCHECK(frontend);
    360 
    361   syncer::ModelSafeRoutingInfo routing_info;
    362   std::vector<syncer::ModelSafeWorker*> workers;
    363   registrar_->GetModelSafeRoutingInfo(&routing_info);
    364   registrar_->GetWorkers(&workers);
    365 
    366   InternalComponentsFactory::Switches factory_switches = {
    367       InternalComponentsFactory::ENCRYPTION_KEYSTORE,
    368       InternalComponentsFactory::BACKOFF_NORMAL
    369   };
    370 
    371   CommandLine* cl = CommandLine::ForCurrentProcess();
    372   if (cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) {
    373     factory_switches.backoff_override =
    374         InternalComponentsFactoryImpl::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE;
    375   }
    376   if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) {
    377     factory_switches.pre_commit_updates_policy =
    378         InternalComponentsFactoryImpl::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE;
    379   }
    380 
    381   initialization_state_ = CREATING_SYNC_MANAGER;
    382 
    383   scoped_ptr<DoInitializeOptions> init_opts(new DoInitializeOptions(
    384       registrar_->sync_thread()->message_loop(),
    385       registrar_.get(),
    386       routing_info,
    387       workers,
    388       extensions_activity_monitor_.GetExtensionsActivity(),
    389       event_handler,
    390       sync_service_url,
    391       base::Bind(&MakeHttpBridgeFactory,
    392                  make_scoped_refptr(profile_->GetRequestContext()),
    393                  NetworkTimeTracker::BuildNotifierUpdateCallback()),
    394       credentials,
    395       invalidator_->GetInvalidatorClientId(),
    396       sync_manager_factory.Pass(),
    397       delete_sync_data_folder,
    398       sync_prefs_->GetEncryptionBootstrapToken(),
    399       sync_prefs_->GetKeystoreEncryptionBootstrapToken(),
    400       scoped_ptr<InternalComponentsFactory>(
    401           new InternalComponentsFactoryImpl(factory_switches)).Pass(),
    402       unrecoverable_error_handler.Pass(),
    403       report_unrecoverable_error_function,
    404       !cl->HasSwitch(switches::kSyncDisableOAuth2Token)));
    405   InitCore(init_opts.Pass());
    406 }
    407 
    408 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) {
    409   DCHECK(registrar_->sync_thread()->IsRunning());
    410   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    411       base::Bind(&SyncBackendHost::Core::DoUpdateCredentials,
    412                  core_.get(),
    413                  credentials));
    414 }
    415 
    416 void SyncBackendHost::StartSyncingWithServer() {
    417   SDVLOG(1) << "SyncBackendHost::StartSyncingWithServer called.";
    418 
    419   syncer::ModelSafeRoutingInfo routing_info;
    420   registrar_->GetModelSafeRoutingInfo(&routing_info);
    421 
    422   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    423       base::Bind(&SyncBackendHost::Core::DoStartSyncing,
    424                  core_.get(), routing_info));
    425 }
    426 
    427 void SyncBackendHost::SetEncryptionPassphrase(const std::string& passphrase,
    428                                               bool is_explicit) {
    429   DCHECK(registrar_->sync_thread()->IsRunning());
    430   if (!IsNigoriEnabled()) {
    431     NOTREACHED() << "SetEncryptionPassphrase must never be called when nigori"
    432                     " is disabled.";
    433     return;
    434   }
    435 
    436   // We should never be called with an empty passphrase.
    437   DCHECK(!passphrase.empty());
    438 
    439   // This should only be called by the frontend.
    440   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
    441 
    442   // SetEncryptionPassphrase should never be called if we are currently
    443   // encrypted with an explicit passphrase.
    444   DCHECK(cached_passphrase_type_ == syncer::KEYSTORE_PASSPHRASE ||
    445          cached_passphrase_type_ == syncer::IMPLICIT_PASSPHRASE);
    446 
    447   // Post an encryption task on the syncer thread.
    448   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    449       base::Bind(&SyncBackendHost::Core::DoSetEncryptionPassphrase,
    450                  core_.get(),
    451                  passphrase, is_explicit));
    452 }
    453 
    454 bool SyncBackendHost::SetDecryptionPassphrase(const std::string& passphrase) {
    455   if (!IsNigoriEnabled()) {
    456     NOTREACHED() << "SetDecryptionPassphrase must never be called when nigori"
    457                     " is disabled.";
    458     return false;
    459   }
    460 
    461   // We should never be called with an empty passphrase.
    462   DCHECK(!passphrase.empty());
    463 
    464   // This should only be called by the frontend.
    465   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
    466 
    467   // This should only be called when we have cached pending keys.
    468   DCHECK(cached_pending_keys_.has_blob());
    469 
    470   // Check the passphrase that was provided against our local cache of the
    471   // cryptographer's pending keys. If this was unsuccessful, the UI layer can
    472   // immediately call OnPassphraseRequired without showing the user a spinner.
    473   if (!CheckPassphraseAgainstCachedPendingKeys(passphrase))
    474     return false;
    475 
    476   // Post a decryption task on the syncer thread.
    477   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    478       base::Bind(&SyncBackendHost::Core::DoSetDecryptionPassphrase,
    479                  core_.get(),
    480                  passphrase));
    481 
    482   // Since we were able to decrypt the cached pending keys with the passphrase
    483   // provided, we immediately alert the UI layer that the passphrase was
    484   // accepted. This will avoid the situation where a user enters a passphrase,
    485   // clicks OK, immediately reopens the advanced settings dialog, and gets an
    486   // unnecessary prompt for a passphrase.
    487   // Note: It is not guaranteed that the passphrase will be accepted by the
    488   // syncer thread, since we could receive a new nigori node while the task is
    489   // pending. This scenario is a valid race, and SetDecryptionPassphrase can
    490   // trigger a new OnPassphraseRequired if it needs to.
    491   NotifyPassphraseAccepted();
    492   return true;
    493 }
    494 
    495 void SyncBackendHost::StopSyncManagerForShutdown() {
    496   DCHECK_GT(initialization_state_, NOT_ATTEMPTED);
    497   if (initialization_state_ == CREATING_SYNC_MANAGER) {
    498     // We post here to implicitly wait for the SyncManager to be created,
    499     // if needed.  We have to wait, since we need to shutdown immediately,
    500     // and we need to tell the SyncManager so it can abort any activity
    501     // (net I/O, data application).
    502     DCHECK(registrar_->sync_thread()->IsRunning());
    503     registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    504         base::Bind(&SyncBackendHost::Core::DoStopSyncManagerForShutdown,
    505                    core_.get()));
    506   } else {
    507     core_->DoStopSyncManagerForShutdown();
    508   }
    509 }
    510 
    511 void SyncBackendHost::StopSyncingForShutdown() {
    512   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
    513 
    514   // Immediately stop sending messages to the frontend.
    515   frontend_ = NULL;
    516 
    517   // Stop listening for and forwarding locally-triggered sync refresh requests.
    518   notification_registrar_.RemoveAll();
    519 
    520   DCHECK(registrar_->sync_thread()->IsRunning());
    521 
    522   registrar_->RequestWorkerStopOnUIThread();
    523 
    524   StopSyncManagerForShutdown();
    525 }
    526 
    527 scoped_ptr<base::Thread> SyncBackendHost::Shutdown(ShutdownOption option) {
    528   // StopSyncingForShutdown() (which nulls out |frontend_|) should be
    529   // called first.
    530   DCHECK(!frontend_);
    531   DCHECK(registrar_->sync_thread()->IsRunning());
    532 
    533   bool sync_disabled = (option == DISABLE_AND_CLAIM_THREAD);
    534   bool sync_thread_claimed =
    535       (option == DISABLE_AND_CLAIM_THREAD || option == STOP_AND_CLAIM_THREAD);
    536 
    537   if (invalidation_handler_registered_) {
    538     if (sync_disabled) {
    539       UnregisterInvalidationIds();
    540     }
    541     invalidator_->UnregisterInvalidationHandler(this);
    542     invalidator_ = NULL;
    543   }
    544   invalidation_handler_registered_ = false;
    545 
    546   // Shut down and destroy sync manager.
    547   registrar_->sync_thread()->message_loop()->PostTask(
    548       FROM_HERE,
    549       base::Bind(&SyncBackendHost::Core::DoShutdown,
    550                  core_.get(), sync_disabled));
    551   core_ = NULL;
    552 
    553   // Worker cleanup.
    554   SyncBackendRegistrar* detached_registrar = registrar_.release();
    555   detached_registrar->sync_thread()->message_loop()->PostTask(
    556       FROM_HERE,
    557       base::Bind(&SyncBackendRegistrar::Shutdown,
    558                  base::Unretained(detached_registrar)));
    559 
    560   js_backend_.Reset();
    561   if (sync_thread_claimed)
    562     return detached_registrar->ReleaseSyncThread();
    563   else
    564     return scoped_ptr<base::Thread>();
    565 }
    566 
    567 void SyncBackendHost::UnregisterInvalidationIds() {
    568   if (invalidation_handler_registered_) {
    569     invalidator_->UpdateRegisteredInvalidationIds(
    570         this,
    571         syncer::ObjectIdSet());
    572   }
    573 }
    574 
    575 void SyncBackendHost::ConfigureDataTypes(
    576     syncer::ConfigureReason reason,
    577     const DataTypeConfigStateMap& config_state_map,
    578     const base::Callback<void(syncer::ModelTypeSet,
    579                               syncer::ModelTypeSet)>& ready_task,
    580     const base::Callback<void()>& retry_callback) {
    581   // Only one configure is allowed at a time.  This is guaranteed by our
    582   // callers.  The SyncBackendHost requests one configure as the backend is
    583   // initializing and waits for it to complete.  After initialization, all
    584   // configurations will pass through the DataTypeManager, which is careful to
    585   // never send a new configure request until the current request succeeds.
    586 
    587   DCHECK_EQ(initialization_state_, INITIALIZED);
    588 
    589   // The SyncBackendRegistrar's routing info will be updated by adding the
    590   // types_to_add to the list then removing types_to_remove.  Any types which
    591   // are not in either of those sets will remain untouched.
    592   //
    593   // Types which were not in the list previously are not fully downloaded, so we
    594   // must ask the syncer to download them.  Any newly supported datatypes will
    595   // not have been in that routing info list, so they will be among the types
    596   // downloaded if they are enabled.
    597   //
    598   // The SyncBackendRegistrar's state was initially derived from the types
    599   // detected to have been downloaded in the database.  Afterwards it is
    600   // modified only by this function.  We expect it to remain in sync with the
    601   // backend because configuration requests are never aborted; they are retried
    602   // until they succeed or the backend is shut down.
    603 
    604   syncer::ModelTypeSet previous_types = registrar_->GetLastConfiguredTypes();
    605 
    606   syncer::ModelTypeSet disabled_types =
    607       GetDataTypesInState(DISABLED, config_state_map);
    608   syncer::ModelTypeSet fatal_types =
    609       GetDataTypesInState(FATAL, config_state_map);
    610   syncer::ModelTypeSet crypto_types =
    611       GetDataTypesInState(CRYPTO, config_state_map);
    612   disabled_types.PutAll(fatal_types);
    613   disabled_types.PutAll(crypto_types);
    614   syncer::ModelTypeSet active_types =
    615       GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map);
    616   syncer::ModelTypeSet clean_first_types =
    617       GetDataTypesInState(CONFIGURE_CLEAN, config_state_map);
    618   syncer::ModelTypeSet types_to_download = registrar_->ConfigureDataTypes(
    619       syncer::Union(active_types, clean_first_types),
    620       disabled_types);
    621   types_to_download.PutAll(clean_first_types);
    622   types_to_download.RemoveAll(syncer::ProxyTypes());
    623   if (!types_to_download.Empty())
    624     types_to_download.Put(syncer::NIGORI);
    625 
    626   // TODO(sync): crbug.com/137550.
    627   // It's dangerous to configure types that have progress markers.  Types with
    628   // progress markers can trigger a MIGRATION_DONE response.  We are not
    629   // prepared to handle a migration during a configure, so we must ensure that
    630   // all our types_to_download actually contain no data before we sync them.
    631   //
    632   // One common way to end up in this situation used to be types which
    633   // downloaded some or all of their data but have not applied it yet.  We avoid
    634   // problems with those types by purging the data of any such partially synced
    635   // types soon after we load the directory.
    636   //
    637   // Another possible scenario is that we have newly supported or newly enabled
    638   // data types being downloaded here but the nigori type, which is always
    639   // included in any GetUpdates request, requires migration.  The server has
    640   // code to detect this scenario based on the configure reason, the fact that
    641   // the nigori type is the only requested type which requires migration, and
    642   // that the requested types list includes at least one non-nigori type.  It
    643   // will not send a MIGRATION_DONE response in that case.  We still need to be
    644   // careful to not send progress markers for non-nigori types, though.  If a
    645   // non-nigori type in the request requires migration, a MIGRATION_DONE
    646   // response will be sent.
    647 
    648   syncer::ModelSafeRoutingInfo routing_info;
    649   registrar_->GetModelSafeRoutingInfo(&routing_info);
    650 
    651   syncer::ModelTypeSet current_types = registrar_->GetLastConfiguredTypes();
    652   syncer::ModelTypeSet types_to_purge =
    653       syncer::Difference(previous_types, current_types);
    654   syncer::ModelTypeSet inactive_types =
    655       GetDataTypesInState(CONFIGURE_INACTIVE, config_state_map);
    656   types_to_purge.RemoveAll(inactive_types);
    657 
    658   DCHECK(syncer::Intersection(current_types, fatal_types).Empty());
    659   DCHECK(syncer::Intersection(current_types, crypto_types).Empty());
    660   DCHECK(current_types.HasAll(types_to_download));
    661 
    662   SDVLOG(1) << "Types "
    663             << syncer::ModelTypeSetToString(types_to_download)
    664             << " added; calling DoConfigureSyncer";
    665   // Divide up the types into their corresponding actions (each is mutually
    666   // exclusive):
    667   // - Types which have just been added to the routing info (types_to_download):
    668   //   are downloaded.
    669   // - Types which have encountered a fatal error (fatal_types) are deleted
    670   //   from the directory and journaled in the delete journal.
    671   // - Types which have encountered a cryptographer error (crypto_types) are
    672   //   unapplied (local state is purged but sync state is not).
    673   // - All other types not in the routing info (types just disabled) are deleted
    674   //   from the directory.
    675   // - Everything else (enabled types and already disabled types) is not
    676   //   touched.
    677   RequestConfigureSyncer(reason,
    678                          types_to_download,
    679                          types_to_purge,
    680                          fatal_types,
    681                          syncer::Union(crypto_types, clean_first_types),
    682                          inactive_types,
    683                          routing_info,
    684                          ready_task,
    685                          retry_callback);
    686 }
    687 
    688 void SyncBackendHost::EnableEncryptEverything() {
    689   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    690      base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything,
    691                 core_.get()));
    692 }
    693 
    694 void SyncBackendHost::ActivateDataType(
    695     syncer::ModelType type, syncer::ModelSafeGroup group,
    696     ChangeProcessor* change_processor) {
    697   registrar_->ActivateDataType(type, group, change_processor, GetUserShare());
    698 }
    699 
    700 void SyncBackendHost::DeactivateDataType(syncer::ModelType type) {
    701   registrar_->DeactivateDataType(type);
    702 }
    703 
    704 syncer::UserShare* SyncBackendHost::GetUserShare() const {
    705   return core_->sync_manager()->GetUserShare();
    706 }
    707 
    708 SyncBackendHost::Status SyncBackendHost::GetDetailedStatus() {
    709   DCHECK(initialized());
    710   return core_->sync_manager()->GetDetailedStatus();
    711 }
    712 
    713 SyncSessionSnapshot SyncBackendHost::GetLastSessionSnapshot() const {
    714   return last_snapshot_;
    715 }
    716 
    717 bool SyncBackendHost::HasUnsyncedItems() const {
    718   DCHECK(initialized());
    719   return core_->sync_manager()->HasUnsyncedItems();
    720 }
    721 
    722 bool SyncBackendHost::IsNigoriEnabled() const {
    723   return registrar_.get() && registrar_->IsNigoriEnabled();
    724 }
    725 
    726 syncer::PassphraseType SyncBackendHost::GetPassphraseType() const {
    727   return cached_passphrase_type_;
    728 }
    729 
    730 base::Time SyncBackendHost::GetExplicitPassphraseTime() const {
    731   return cached_explicit_passphrase_time_;
    732 }
    733 
    734 bool SyncBackendHost::IsCryptographerReady(
    735     const syncer::BaseTransaction* trans) const {
    736   return initialized() && trans->GetCryptographer()->is_ready();
    737 }
    738 
    739 void SyncBackendHost::GetModelSafeRoutingInfo(
    740     syncer::ModelSafeRoutingInfo* out) const {
    741   if (initialized()) {
    742     CHECK(registrar_.get());
    743     registrar_->GetModelSafeRoutingInfo(out);
    744   } else {
    745     NOTREACHED();
    746   }
    747 }
    748 
    749 SyncedDeviceTracker* SyncBackendHost::GetSyncedDeviceTracker() const {
    750   if (!initialized())
    751     return NULL;
    752   return core_->synced_device_tracker();
    753 }
    754 
    755 void SyncBackendHost::InitCore(scoped_ptr<DoInitializeOptions> options) {
    756   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    757       base::Bind(&SyncBackendHost::Core::DoInitialize,
    758                  core_.get(), base::Passed(&options)));
    759 }
    760 
    761 void SyncBackendHost::RequestConfigureSyncer(
    762     syncer::ConfigureReason reason,
    763     syncer::ModelTypeSet to_download,
    764     syncer::ModelTypeSet to_purge,
    765     syncer::ModelTypeSet to_journal,
    766     syncer::ModelTypeSet to_unapply,
    767     syncer::ModelTypeSet to_ignore,
    768     const syncer::ModelSafeRoutingInfo& routing_info,
    769     const base::Callback<void(syncer::ModelTypeSet,
    770                               syncer::ModelTypeSet)>& ready_task,
    771     const base::Closure& retry_callback) {
    772   DoConfigureSyncerTypes config_types;
    773   config_types.to_download = to_download;
    774   config_types.to_purge = to_purge;
    775   config_types.to_journal = to_journal;
    776   config_types.to_unapply = to_unapply;
    777   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    778        base::Bind(&SyncBackendHost::Core::DoConfigureSyncer,
    779                   core_.get(),
    780                   reason,
    781                   config_types,
    782                   routing_info,
    783                   ready_task,
    784                   retry_callback));
    785 }
    786 
    787 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop(
    788     const syncer::ModelTypeSet enabled_types,
    789     const syncer::ModelTypeSet succeeded_configuration_types,
    790     const syncer::ModelTypeSet failed_configuration_types,
    791     const base::Callback<void(syncer::ModelTypeSet,
    792                               syncer::ModelTypeSet)>& ready_task) {
    793   if (!frontend_)
    794     return;
    795 
    796   invalidator_->UpdateRegisteredInvalidationIds(
    797       this,
    798       ModelTypeSetToObjectIdSet(enabled_types));
    799 
    800   if (!ready_task.is_null())
    801     ready_task.Run(succeeded_configuration_types, failed_configuration_types);
    802 }
    803 
    804 void SyncBackendHost::HandleSyncManagerInitializationOnFrontendLoop(
    805     const syncer::WeakHandle<syncer::JsBackend>& js_backend,
    806     const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
    807         debug_info_listener,
    808     syncer::ModelTypeSet restored_types) {
    809   DCHECK_EQ(initialization_state_, CREATING_SYNC_MANAGER);
    810   DCHECK(!js_backend_.IsInitialized());
    811 
    812   initialization_state_ = INITIALIZATING_CONTROL_TYPES;
    813 
    814   js_backend_ = js_backend;
    815   debug_info_listener_ = debug_info_listener;
    816 
    817   invalidator_->RegisterInvalidationHandler(this);
    818   invalidation_handler_registered_ = true;
    819 
    820   // Inform the registrar of those types that have been fully downloaded and
    821   // applied.
    822   registrar_->SetInitialTypes(restored_types);
    823 
    824   // Start forwarding refresh requests to the SyncManager
    825   notification_registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
    826                               content::Source<Profile>(profile_));
    827 
    828   syncer::ConfigureReason reason =
    829       (sync_prefs_->HasSyncSetupCompleted() ?
    830        syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE :
    831        syncer::CONFIGURE_REASON_NEW_CLIENT);
    832 
    833   // Fake a state change to initialize the SyncManager's cached invalidator
    834   // state.
    835   OnInvalidatorStateChange(invalidator_->GetInvalidatorState());
    836 
    837   // Kick off the next step in SyncBackendHost initialization by downloading
    838   // any necessary control types.
    839   registrar_->sync_thread()->message_loop()->PostTask(
    840       FROM_HERE,
    841       base::Bind(&SyncBackendHost::Core::DoDownloadControlTypes,
    842                  core_.get(),
    843                  reason));
    844 }
    845 
    846 void SyncBackendHost::Observe(
    847     int type,
    848     const content::NotificationSource& source,
    849     const content::NotificationDetails& details) {
    850   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    851   DCHECK_EQ(type, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL);
    852 
    853   content::Details<const syncer::ModelTypeSet> state_details(details);
    854   const syncer::ModelTypeSet& types = *(state_details.ptr());
    855   registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
    856       base::Bind(&SyncBackendHost::Core::DoRefreshTypes, core_.get(), types));
    857 }
    858 
    859 SyncBackendHost::DoInitializeOptions::DoInitializeOptions(
    860     base::MessageLoop* sync_loop,
    861     SyncBackendRegistrar* registrar,
    862     const syncer::ModelSafeRoutingInfo& routing_info,
    863     const std::vector<syncer::ModelSafeWorker*>& workers,
    864     const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity,
    865     const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
    866     const GURL& service_url,
    867     MakeHttpBridgeFactoryFn make_http_bridge_factory_fn,
    868     const syncer::SyncCredentials& credentials,
    869     const std::string& invalidator_client_id,
    870     scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
    871     bool delete_sync_data_folder,
    872     const std::string& restored_key_for_bootstrapping,
    873     const std::string& restored_keystore_key_for_bootstrapping,
    874     scoped_ptr<InternalComponentsFactory> internal_components_factory,
    875     scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
    876     syncer::ReportUnrecoverableErrorFunction
    877         report_unrecoverable_error_function,
    878     bool use_oauth2_token)
    879     : sync_loop(sync_loop),
    880       registrar(registrar),
    881       routing_info(routing_info),
    882       workers(workers),
    883       extensions_activity(extensions_activity),
    884       event_handler(event_handler),
    885       service_url(service_url),
    886       make_http_bridge_factory_fn(make_http_bridge_factory_fn),
    887       credentials(credentials),
    888       invalidator_client_id(invalidator_client_id),
    889       sync_manager_factory(sync_manager_factory.Pass()),
    890       delete_sync_data_folder(delete_sync_data_folder),
    891       restored_key_for_bootstrapping(restored_key_for_bootstrapping),
    892       restored_keystore_key_for_bootstrapping(
    893           restored_keystore_key_for_bootstrapping),
    894       internal_components_factory(internal_components_factory.Pass()),
    895       unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
    896       report_unrecoverable_error_function(
    897           report_unrecoverable_error_function),
    898       use_oauth2_token(use_oauth2_token) {
    899 }
    900 
    901 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {}
    902 
    903 SyncBackendHost::Core::Core(const std::string& name,
    904                             const base::FilePath& sync_data_folder_path,
    905                             const base::WeakPtr<SyncBackendHost>& backend)
    906     : name_(name),
    907       sync_data_folder_path_(sync_data_folder_path),
    908       host_(backend),
    909       sync_loop_(NULL),
    910       registrar_(NULL),
    911       weak_ptr_factory_(this) {
    912   DCHECK(backend.get());
    913 }
    914 
    915 SyncBackendHost::Core::~Core() {
    916   DCHECK(!sync_manager_.get());
    917 }
    918 
    919 void SyncBackendHost::Core::OnSyncCycleCompleted(
    920     const SyncSessionSnapshot& snapshot) {
    921   if (!sync_loop_)
    922     return;
    923   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
    924 
    925   host_.Call(
    926       FROM_HERE,
    927       &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop,
    928       snapshot);
    929 }
    930 
    931 void SyncBackendHost::Core::DoDownloadControlTypes(
    932     syncer::ConfigureReason reason) {
    933   syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes(
    934       syncer::ControlTypes(), syncer::ModelTypeSet());
    935   syncer::ModelSafeRoutingInfo routing_info;
    936   registrar_->GetModelSafeRoutingInfo(&routing_info);
    937   SDVLOG(1) << "Control Types "
    938             << syncer::ModelTypeSetToString(new_control_types)
    939             << " added; calling ConfigureSyncer";
    940 
    941   syncer::ModelTypeSet types_to_purge =
    942       syncer::Difference(syncer::ModelTypeSet::All(),
    943                          GetRoutingInfoTypes(routing_info));
    944 
    945   sync_manager_->ConfigureSyncer(
    946       reason,
    947       new_control_types,
    948       types_to_purge,
    949       syncer::ModelTypeSet(),
    950       syncer::ModelTypeSet(),
    951       routing_info,
    952       base::Bind(&SyncBackendHost::Core::DoInitialProcessControlTypes,
    953                  weak_ptr_factory_.GetWeakPtr()),
    954       base::Bind(&SyncBackendHost::Core::OnControlTypesDownloadRetry,
    955                  weak_ptr_factory_.GetWeakPtr()));
    956 }
    957 
    958 void SyncBackendHost::Core::DoRefreshTypes(syncer::ModelTypeSet types) {
    959   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
    960   sync_manager_->RefreshTypes(types);
    961 }
    962 
    963 void SyncBackendHost::Core::OnControlTypesDownloadRetry() {
    964   host_.Call(FROM_HERE,
    965              &SyncBackendHost::HandleControlTypesDownloadRetry);
    966 }
    967 
    968 void SyncBackendHost::Core::OnInitializationComplete(
    969     const syncer::WeakHandle<syncer::JsBackend>& js_backend,
    970     const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
    971         debug_info_listener,
    972     bool success,
    973     const syncer::ModelTypeSet restored_types) {
    974   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
    975 
    976   if (!success) {
    977     DoDestroySyncManager();
    978     host_.Call(FROM_HERE,
    979                &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop,
    980                false);
    981     return;
    982   }
    983 
    984   // Register for encryption related changes now. We have to do this before
    985   // the initializing downloading control types or initializing the encryption
    986   // handler in order to receive notifications triggered during encryption
    987   // startup.
    988   sync_manager_->GetEncryptionHandler()->AddObserver(this);
    989 
    990   // Sync manager initialization is complete, so we can schedule recurring
    991   // SaveChanges.
    992   sync_loop_->PostTask(FROM_HERE,
    993                        base::Bind(&Core::StartSavingChanges,
    994                                   weak_ptr_factory_.GetWeakPtr()));
    995 
    996   host_.Call(FROM_HERE,
    997              &SyncBackendHost::HandleSyncManagerInitializationOnFrontendLoop,
    998              js_backend,
    999              debug_info_listener,
   1000              restored_types);
   1001 }
   1002 
   1003 void SyncBackendHost::Core::OnConnectionStatusChange(
   1004     syncer::ConnectionStatus status) {
   1005   if (!sync_loop_)
   1006     return;
   1007   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1008   host_.Call(
   1009       FROM_HERE,
   1010       &SyncBackendHost::HandleConnectionStatusChangeOnFrontendLoop, status);
   1011 }
   1012 
   1013 void SyncBackendHost::Core::OnPassphraseRequired(
   1014     syncer::PassphraseRequiredReason reason,
   1015     const sync_pb::EncryptedData& pending_keys) {
   1016   if (!sync_loop_)
   1017     return;
   1018   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1019   host_.Call(
   1020       FROM_HERE,
   1021       &SyncBackendHost::NotifyPassphraseRequired, reason, pending_keys);
   1022 }
   1023 
   1024 void SyncBackendHost::Core::OnPassphraseAccepted() {
   1025   if (!sync_loop_)
   1026     return;
   1027   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1028   host_.Call(
   1029       FROM_HERE,
   1030       &SyncBackendHost::NotifyPassphraseAccepted);
   1031 }
   1032 
   1033 void SyncBackendHost::Core::OnBootstrapTokenUpdated(
   1034     const std::string& bootstrap_token,
   1035     syncer::BootstrapTokenType type) {
   1036   if (!sync_loop_)
   1037     return;
   1038   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1039   host_.Call(FROM_HERE,
   1040              &SyncBackendHost::PersistEncryptionBootstrapToken,
   1041              bootstrap_token,
   1042              type);
   1043 }
   1044 
   1045 void SyncBackendHost::Core::OnStopSyncingPermanently() {
   1046   if (!sync_loop_)
   1047     return;
   1048   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1049   host_.Call(
   1050       FROM_HERE,
   1051       &SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop);
   1052 }
   1053 
   1054 void SyncBackendHost::Core::OnUpdatedToken(const std::string& token) {
   1055   if (!sync_loop_)
   1056     return;
   1057   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1058   host_.Call(
   1059       FROM_HERE,
   1060       &SyncBackendHost::NotifyUpdatedToken, token);
   1061 }
   1062 
   1063 void SyncBackendHost::Core::OnEncryptedTypesChanged(
   1064     syncer::ModelTypeSet encrypted_types,
   1065     bool encrypt_everything) {
   1066   if (!sync_loop_)
   1067     return;
   1068   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1069   // NOTE: We're in a transaction.
   1070   host_.Call(
   1071       FROM_HERE,
   1072       &SyncBackendHost::NotifyEncryptedTypesChanged,
   1073       encrypted_types, encrypt_everything);
   1074 }
   1075 
   1076 void SyncBackendHost::Core::OnEncryptionComplete() {
   1077   if (!sync_loop_)
   1078     return;
   1079   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1080   // NOTE: We're in a transaction.
   1081   host_.Call(
   1082       FROM_HERE,
   1083       &SyncBackendHost::NotifyEncryptionComplete);
   1084 }
   1085 
   1086 void SyncBackendHost::Core::OnCryptographerStateChanged(
   1087     syncer::Cryptographer* cryptographer) {
   1088   // Do nothing.
   1089 }
   1090 
   1091 void SyncBackendHost::Core::OnPassphraseTypeChanged(
   1092     syncer::PassphraseType type, base::Time passphrase_time) {
   1093   host_.Call(
   1094       FROM_HERE,
   1095       &SyncBackendHost::HandlePassphraseTypeChangedOnFrontendLoop,
   1096       type, passphrase_time);
   1097 }
   1098 
   1099 void SyncBackendHost::Core::OnActionableError(
   1100     const syncer::SyncProtocolError& sync_error) {
   1101   if (!sync_loop_)
   1102     return;
   1103   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1104   host_.Call(
   1105       FROM_HERE,
   1106       &SyncBackendHost::HandleActionableErrorEventOnFrontendLoop,
   1107       sync_error);
   1108 }
   1109 
   1110 void SyncBackendHost::Core::DoOnInvalidatorStateChange(
   1111     syncer::InvalidatorState state) {
   1112   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1113   sync_manager_->OnInvalidatorStateChange(state);
   1114 }
   1115 
   1116 void SyncBackendHost::Core::DoOnIncomingInvalidation(
   1117     syncer::ObjectIdInvalidationMap invalidation_map) {
   1118   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1119   sync_manager_->OnIncomingInvalidation(invalidation_map);
   1120 }
   1121 
   1122 void SyncBackendHost::Core::DoInitialize(
   1123     scoped_ptr<DoInitializeOptions> options) {
   1124   DCHECK(!sync_loop_);
   1125   sync_loop_ = options->sync_loop;
   1126   DCHECK(sync_loop_);
   1127 
   1128   // Blow away the partial or corrupt sync data folder before doing any more
   1129   // initialization, if necessary.
   1130   if (options->delete_sync_data_folder) {
   1131     DeleteSyncDataFolder();
   1132   }
   1133 
   1134   // Make sure that the directory exists before initializing the backend.
   1135   // If it already exists, this will do no harm.
   1136   if (!file_util::CreateDirectory(sync_data_folder_path_)) {
   1137     DLOG(FATAL) << "Sync Data directory creation failed.";
   1138   }
   1139 
   1140   DCHECK(!registrar_);
   1141   registrar_ = options->registrar;
   1142   DCHECK(registrar_);
   1143 
   1144   sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_);
   1145   sync_manager_->AddObserver(this);
   1146   sync_manager_->Init(sync_data_folder_path_,
   1147                       options->event_handler,
   1148                       options->service_url.host() + options->service_url.path(),
   1149                       options->service_url.EffectiveIntPort(),
   1150                       options->service_url.SchemeIsSecure(),
   1151                       options->make_http_bridge_factory_fn.Run().Pass(),
   1152                       options->workers,
   1153                       options->extensions_activity,
   1154                       options->registrar /* as SyncManager::ChangeDelegate */,
   1155                       options->credentials,
   1156                       options->invalidator_client_id,
   1157                       options->restored_key_for_bootstrapping,
   1158                       options->restored_keystore_key_for_bootstrapping,
   1159                       options->internal_components_factory.get(),
   1160                       &encryptor_,
   1161                       options->unrecoverable_error_handler.Pass(),
   1162                       options->report_unrecoverable_error_function,
   1163                       options->use_oauth2_token);
   1164 
   1165   // |sync_manager_| may end up being NULL here in tests (in
   1166   // synchronous initialization mode).
   1167   //
   1168   // TODO(akalin): Fix this behavior (see http://crbug.com/140354).
   1169   if (sync_manager_) {
   1170     // Now check the command line to see if we need to simulate an
   1171     // unrecoverable error for testing purpose. Note the error is thrown
   1172     // only if the initialization succeeded. Also it makes sense to use this
   1173     // flag only when restarting the browser with an account already setup. If
   1174     // you use this before setting up the setup would not succeed as an error
   1175     // would be encountered.
   1176     if (CommandLine::ForCurrentProcess()->HasSwitch(
   1177             switches::kSyncThrowUnrecoverableError)) {
   1178       sync_manager_->ThrowUnrecoverableError();
   1179     }
   1180   }
   1181 }
   1182 
   1183 void SyncBackendHost::Core::DoUpdateCredentials(
   1184     const SyncCredentials& credentials) {
   1185   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1186   // UpdateCredentials can be called during backend initialization, possibly
   1187   // when backend initialization has failed but hasn't notified the UI thread
   1188   // yet. In that case, the sync manager may have been destroyed on the sync
   1189   // thread before this task was executed, so we do nothing.
   1190   if (sync_manager_) {
   1191     sync_manager_->UpdateCredentials(credentials);
   1192   }
   1193 }
   1194 
   1195 void SyncBackendHost::Core::DoStartSyncing(
   1196     const syncer::ModelSafeRoutingInfo& routing_info) {
   1197   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1198   sync_manager_->StartSyncingNormally(routing_info);
   1199 }
   1200 
   1201 void SyncBackendHost::Core::DoSetEncryptionPassphrase(
   1202     const std::string& passphrase,
   1203     bool is_explicit) {
   1204   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1205   sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase(
   1206       passphrase, is_explicit);
   1207 }
   1208 
   1209 void SyncBackendHost::Core::DoInitialProcessControlTypes() {
   1210   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1211 
   1212   DVLOG(1) << "Initilalizing Control Types";
   1213 
   1214   // Initialize encryption.
   1215   sync_manager_->GetEncryptionHandler()->Init();
   1216 
   1217   // Note: experiments are currently handled via SBH::AddExperimentalTypes,
   1218   // which is called at the end of every sync cycle.
   1219   // TODO(zea): eventually add an experiment handler and initialize it here.
   1220 
   1221   if (!sync_manager_->GetUserShare()) {  // NULL in some tests.
   1222     DVLOG(1) << "Skipping initialization of DeviceInfo";
   1223     host_.Call(
   1224         FROM_HERE,
   1225         &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop,
   1226         true);
   1227     return;
   1228   }
   1229 
   1230   if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) {
   1231     LOG(ERROR) << "Failed to download control types";
   1232     host_.Call(
   1233         FROM_HERE,
   1234         &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop,
   1235         false);
   1236     return;
   1237   }
   1238 
   1239   // Initialize device info. This is asynchronous on some platforms, so we
   1240   // provide a callback for when it finishes.
   1241   synced_device_tracker_.reset(
   1242       new SyncedDeviceTracker(sync_manager_->GetUserShare(),
   1243                               sync_manager_->cache_guid()));
   1244   synced_device_tracker_->InitLocalDeviceInfo(
   1245       base::Bind(&SyncBackendHost::Core::DoFinishInitialProcessControlTypes,
   1246                  weak_ptr_factory_.GetWeakPtr()));
   1247 }
   1248 
   1249 void SyncBackendHost::Core::DoFinishInitialProcessControlTypes() {
   1250   registrar_->ActivateDataType(syncer::DEVICE_INFO,
   1251                                syncer::GROUP_PASSIVE,
   1252                                synced_device_tracker_.get(),
   1253                                sync_manager_->GetUserShare());
   1254 
   1255   host_.Call(
   1256       FROM_HERE,
   1257       &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop,
   1258       true);
   1259 }
   1260 
   1261 void SyncBackendHost::Core::DoSetDecryptionPassphrase(
   1262     const std::string& passphrase) {
   1263   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1264   sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(
   1265       passphrase);
   1266 }
   1267 
   1268 void SyncBackendHost::Core::DoEnableEncryptEverything() {
   1269   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1270   sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
   1271 }
   1272 
   1273 void SyncBackendHost::Core::DoStopSyncManagerForShutdown() {
   1274   if (sync_manager_)
   1275     sync_manager_->StopSyncingForShutdown();
   1276 }
   1277 
   1278 void SyncBackendHost::Core::DoShutdown(bool sync_disabled) {
   1279   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1280   // It's safe to do this even if the type was never activated.
   1281   registrar_->DeactivateDataType(syncer::DEVICE_INFO);
   1282   synced_device_tracker_.reset();
   1283 
   1284   DoDestroySyncManager();
   1285 
   1286   registrar_ = NULL;
   1287 
   1288   if (sync_disabled)
   1289     DeleteSyncDataFolder();
   1290 
   1291   host_.Reset();
   1292   weak_ptr_factory_.InvalidateWeakPtrs();
   1293 }
   1294 
   1295 void SyncBackendHost::Core::DoDestroySyncManager() {
   1296   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1297   if (sync_manager_) {
   1298     save_changes_timer_.reset();
   1299     sync_manager_->RemoveObserver(this);
   1300     sync_manager_->ShutdownOnSyncThread();
   1301     sync_manager_.reset();
   1302   }
   1303 }
   1304 
   1305 void SyncBackendHost::Core::DoConfigureSyncer(
   1306     syncer::ConfigureReason reason,
   1307     const DoConfigureSyncerTypes& config_types,
   1308     const syncer::ModelSafeRoutingInfo routing_info,
   1309     const base::Callback<void(syncer::ModelTypeSet,
   1310                               syncer::ModelTypeSet)>& ready_task,
   1311     const base::Closure& retry_callback) {
   1312   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1313   sync_manager_->ConfigureSyncer(
   1314       reason,
   1315       config_types.to_download,
   1316       config_types.to_purge,
   1317       config_types.to_journal,
   1318       config_types.to_unapply,
   1319       routing_info,
   1320       base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes,
   1321                  weak_ptr_factory_.GetWeakPtr(),
   1322                  config_types.to_download,
   1323                  ready_task),
   1324       base::Bind(&SyncBackendHost::Core::DoRetryConfiguration,
   1325                  weak_ptr_factory_.GetWeakPtr(),
   1326                  retry_callback));
   1327 }
   1328 
   1329 void SyncBackendHost::Core::DoFinishConfigureDataTypes(
   1330     syncer::ModelTypeSet types_to_config,
   1331     const base::Callback<void(syncer::ModelTypeSet,
   1332                               syncer::ModelTypeSet)>& ready_task) {
   1333   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1334 
   1335   // Update the enabled types for the bridge and sync manager.
   1336   syncer::ModelSafeRoutingInfo routing_info;
   1337   registrar_->GetModelSafeRoutingInfo(&routing_info);
   1338   syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info);
   1339   enabled_types.RemoveAll(syncer::ProxyTypes());
   1340 
   1341   const syncer::ModelTypeSet failed_configuration_types =
   1342       Difference(types_to_config, sync_manager_->InitialSyncEndedTypes());
   1343   const syncer::ModelTypeSet succeeded_configuration_types =
   1344       Difference(types_to_config, failed_configuration_types);
   1345   host_.Call(FROM_HERE,
   1346              &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop,
   1347              enabled_types,
   1348              succeeded_configuration_types,
   1349              failed_configuration_types,
   1350              ready_task);
   1351 }
   1352 
   1353 void SyncBackendHost::Core::DoRetryConfiguration(
   1354     const base::Closure& retry_callback) {
   1355   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1356   host_.Call(FROM_HERE,
   1357              &SyncBackendHost::RetryConfigurationOnFrontendLoop,
   1358              retry_callback);
   1359 }
   1360 
   1361 void SyncBackendHost::Core::DeleteSyncDataFolder() {
   1362   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1363   if (base::DirectoryExists(sync_data_folder_path_)) {
   1364     if (!base::DeleteFile(sync_data_folder_path_, true))
   1365       SLOG(DFATAL) << "Could not delete the Sync Data folder.";
   1366   }
   1367 }
   1368 
   1369 void SyncBackendHost::Core::StartSavingChanges() {
   1370   // We may already be shut down.
   1371   if (!sync_loop_)
   1372     return;
   1373   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1374   DCHECK(!save_changes_timer_.get());
   1375   save_changes_timer_.reset(new base::RepeatingTimer<Core>());
   1376   save_changes_timer_->Start(FROM_HERE,
   1377       base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds),
   1378       this, &Core::SaveChanges);
   1379 }
   1380 
   1381 void SyncBackendHost::Core::SaveChanges() {
   1382   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   1383   sync_manager_->SaveChanges();
   1384 }
   1385 
   1386 void SyncBackendHost::AddExperimentalTypes() {
   1387   CHECK(initialized());
   1388   syncer::Experiments experiments;
   1389   if (core_->sync_manager()->ReceivedExperiment(&experiments))
   1390     frontend_->OnExperimentsChanged(experiments);
   1391 }
   1392 
   1393 void SyncBackendHost::HandleControlTypesDownloadRetry() {
   1394   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1395   if (!frontend_)
   1396     return;
   1397 
   1398   frontend_->OnSyncConfigureRetry();
   1399 }
   1400 
   1401 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(
   1402     bool success) {
   1403   DCHECK_NE(initialization_state_, NOT_ATTEMPTED);
   1404   if (!frontend_)
   1405     return;
   1406 
   1407   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1408   if (!success) {
   1409     js_backend_.Reset();
   1410     initialization_state_ = NOT_INITIALIZED;
   1411     frontend_->OnBackendInitialized(
   1412         syncer::WeakHandle<syncer::JsBackend>(),
   1413         syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
   1414         false);
   1415     return;
   1416   }
   1417 
   1418   initialization_state_ = INITIALIZED;
   1419 
   1420   // Now that we've downloaded the control types, we can see if there are any
   1421   // experimental types to enable. This should be done before we inform
   1422   // the frontend to ensure they're visible in the customize screen.
   1423   AddExperimentalTypes();
   1424   frontend_->OnBackendInitialized(js_backend_,
   1425                                   debug_info_listener_,
   1426                                   true);
   1427   js_backend_.Reset();
   1428 }
   1429 
   1430 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop(
   1431     const SyncSessionSnapshot& snapshot) {
   1432   if (!frontend_)
   1433     return;
   1434   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1435 
   1436   last_snapshot_ = snapshot;
   1437 
   1438   SDVLOG(1) << "Got snapshot " << snapshot.ToString();
   1439 
   1440   const syncer::ModelTypeSet to_migrate =
   1441       snapshot.model_neutral_state().types_needing_local_migration;
   1442   if (!to_migrate.Empty())
   1443     frontend_->OnMigrationNeededForTypes(to_migrate);
   1444 
   1445   // Process any changes to the datatypes we're syncing.
   1446   // TODO(sync): add support for removing types.
   1447   if (initialized())
   1448     AddExperimentalTypes();
   1449 
   1450   if (initialized())
   1451     frontend_->OnSyncCycleCompleted();
   1452 }
   1453 
   1454 void SyncBackendHost::RetryConfigurationOnFrontendLoop(
   1455     const base::Closure& retry_callback) {
   1456   SDVLOG(1) << "Failed to complete configuration, informing of retry.";
   1457   retry_callback.Run();
   1458 }
   1459 
   1460 void SyncBackendHost::PersistEncryptionBootstrapToken(
   1461     const std::string& token,
   1462     syncer::BootstrapTokenType token_type) {
   1463   CHECK(sync_prefs_.get());
   1464   DCHECK(!token.empty());
   1465   if (token_type == syncer::PASSPHRASE_BOOTSTRAP_TOKEN)
   1466     sync_prefs_->SetEncryptionBootstrapToken(token);
   1467   else
   1468     sync_prefs_->SetKeystoreEncryptionBootstrapToken(token);
   1469 }
   1470 
   1471 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop(
   1472     const syncer::SyncProtocolError& sync_error) {
   1473   if (!frontend_)
   1474     return;
   1475   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1476   frontend_->OnActionableError(sync_error);
   1477 }
   1478 
   1479 void SyncBackendHost::OnInvalidatorStateChange(syncer::InvalidatorState state) {
   1480   registrar_->sync_thread()->message_loop()->PostTask(
   1481       FROM_HERE,
   1482       base::Bind(&SyncBackendHost::Core::DoOnInvalidatorStateChange,
   1483                  core_.get(),
   1484                  state));
   1485 }
   1486 
   1487 void SyncBackendHost::OnIncomingInvalidation(
   1488     const syncer::ObjectIdInvalidationMap& invalidation_map) {
   1489   // TODO(dcheng): Acknowledge immediately for now. Fix this once the
   1490   // invalidator doesn't repeatedly ping for unacknowledged invaliations, since
   1491   // it conflicts with the sync scheduler's internal backoff algorithm.
   1492   // See http://crbug.com/124149 for more information.
   1493   for (syncer::ObjectIdInvalidationMap::const_iterator it =
   1494        invalidation_map.begin(); it != invalidation_map.end(); ++it) {
   1495     invalidator_->AcknowledgeInvalidation(it->first, it->second.ack_handle);
   1496   }
   1497 
   1498   registrar_->sync_thread()->message_loop()->PostTask(
   1499       FROM_HERE,
   1500       base::Bind(&SyncBackendHost::Core::DoOnIncomingInvalidation,
   1501                  core_.get(),
   1502                  invalidation_map));
   1503 }
   1504 
   1505 bool SyncBackendHost::CheckPassphraseAgainstCachedPendingKeys(
   1506     const std::string& passphrase) const {
   1507   DCHECK(cached_pending_keys_.has_blob());
   1508   DCHECK(!passphrase.empty());
   1509   syncer::Nigori nigori;
   1510   nigori.InitByDerivation("localhost", "dummy", passphrase);
   1511   std::string plaintext;
   1512   bool result = nigori.Decrypt(cached_pending_keys_.blob(), &plaintext);
   1513   DVLOG_IF(1, result) << "Passphrase failed to decrypt pending keys.";
   1514   return result;
   1515 }
   1516 
   1517 void SyncBackendHost::NotifyPassphraseRequired(
   1518     syncer::PassphraseRequiredReason reason,
   1519     sync_pb::EncryptedData pending_keys) {
   1520   if (!frontend_)
   1521     return;
   1522 
   1523   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1524 
   1525   // Update our cache of the cryptographer's pending keys.
   1526   cached_pending_keys_ = pending_keys;
   1527 
   1528   frontend_->OnPassphraseRequired(reason, pending_keys);
   1529 }
   1530 
   1531 void SyncBackendHost::NotifyPassphraseAccepted() {
   1532   if (!frontend_)
   1533     return;
   1534 
   1535   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1536 
   1537   // Clear our cache of the cryptographer's pending keys.
   1538   cached_pending_keys_.clear_blob();
   1539   frontend_->OnPassphraseAccepted();
   1540 }
   1541 
   1542 void SyncBackendHost::NotifyUpdatedToken(const std::string& token) {
   1543   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   1544   TokenAvailableDetails details(GaiaConstants::kSyncService, token);
   1545 
   1546   TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
   1547   CHECK(token_service);
   1548   token_service->AddAuthTokenManually(details.service(), details.token());
   1549 }
   1550 
   1551 void SyncBackendHost::NotifyEncryptedTypesChanged(
   1552     syncer::ModelTypeSet encrypted_types,
   1553     bool encrypt_everything) {
   1554   if (!frontend_)
   1555     return;
   1556 
   1557   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1558   frontend_->OnEncryptedTypesChanged(
   1559       encrypted_types, encrypt_everything);
   1560 }
   1561 
   1562 void SyncBackendHost::NotifyEncryptionComplete() {
   1563   if (!frontend_)
   1564     return;
   1565 
   1566   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1567   frontend_->OnEncryptionComplete();
   1568 }
   1569 
   1570 void SyncBackendHost::HandlePassphraseTypeChangedOnFrontendLoop(
   1571     syncer::PassphraseType type,
   1572     base::Time explicit_passphrase_time) {
   1573   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1574   DVLOG(1) << "Passphrase type changed to "
   1575            << syncer::PassphraseTypeToString(type);
   1576   cached_passphrase_type_ = type;
   1577   cached_explicit_passphrase_time_ = explicit_passphrase_time;
   1578 }
   1579 
   1580 void SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop() {
   1581   if (!frontend_)
   1582     return;
   1583   frontend_->OnStopSyncingPermanently();
   1584 }
   1585 
   1586 void SyncBackendHost::HandleConnectionStatusChangeOnFrontendLoop(
   1587     syncer::ConnectionStatus status) {
   1588   if (!frontend_)
   1589     return;
   1590 
   1591   DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
   1592 
   1593   DVLOG(1) << "Connection status changed: "
   1594            << syncer::ConnectionStatusToString(status);
   1595   frontend_->OnConnectionStatusChange(status);
   1596 }
   1597 
   1598 base::MessageLoop* SyncBackendHost::GetSyncLoopForTesting() {
   1599   return registrar_->sync_thread()->message_loop();
   1600 }
   1601 
   1602 #undef SDVLOG
   1603 
   1604 #undef SLOG
   1605 
   1606 }  // namespace browser_sync
   1607