sync_backend_host_core.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/sync_backend_host_core.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/file_util.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/device_info.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/sync_backend_registrar.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/synced_device_tracker.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/chrome_version_info.h"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "sync/internal_api/public/events/protocol_event.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/http_post_provider_factory.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/internal_components_factory.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/commit_counters.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/status_counters.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/sessions/sync_session_snapshot.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/update_counters.h"
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/internal_api/public/sync_core_proxy.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/sync_manager.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/sync_manager_factory.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Helper macros to log with the syncer thread name; useful when there
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// are multiple syncers involved.
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define SLOG(severity) LOG(severity) << name_ << ": "
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": "
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const int kSaveChangesIntervalSeconds = 10;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace syncer {
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class InternalComponentsFactory;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace syncer
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Enums for UMAs.
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)enum SyncBackendInitState {
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SETUP_COMPLETED_FOUND_RESTORED_TYPES = 0,
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SETUP_COMPLETED_NO_RESTORED_TYPES,
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FIRST_SETUP_NO_RESTORED_TYPES,
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FIRST_SETUP_RESTORED_TYPES,
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SYNC_BACKEND_INIT_STATE_COUNT
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace browser_sync {
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoInitializeOptions::DoInitializeOptions(
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::MessageLoop* sync_loop,
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncBackendRegistrar* registrar,
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelSafeRoutingInfo& routing_info,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<scoped_refptr<syncer::ModelSafeWorker> >& workers,
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity,
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& service_url,
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::HttpPostProviderFactory> http_bridge_factory,
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::SyncCredentials& credentials,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& invalidator_client_id,
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool delete_sync_data_folder,
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& restored_key_for_bootstrapping,
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& restored_keystore_key_for_bootstrapping,
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::InternalComponentsFactory> internal_components_factory,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ReportUnrecoverableErrorFunction
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        report_unrecoverable_error_function)
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : sync_loop(sync_loop),
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      registrar(registrar),
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      routing_info(routing_info),
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      workers(workers),
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extensions_activity(extensions_activity),
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      event_handler(event_handler),
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      service_url(service_url),
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      http_bridge_factory(http_bridge_factory.Pass()),
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      credentials(credentials),
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      invalidator_client_id(invalidator_client_id),
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_manager_factory(sync_manager_factory.Pass()),
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      delete_sync_data_folder(delete_sync_data_folder),
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      restored_key_for_bootstrapping(restored_key_for_bootstrapping),
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      restored_keystore_key_for_bootstrapping(
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          restored_keystore_key_for_bootstrapping),
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      internal_components_factory(internal_components_factory.Pass()),
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      report_unrecoverable_error_function(
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          report_unrecoverable_error_function) {
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoInitializeOptions::~DoInitializeOptions() {}
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoConfigureSyncerTypes::DoConfigureSyncerTypes() {}
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoConfigureSyncerTypes::~DoConfigureSyncerTypes() {}
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SyncBackendHostCore::SyncBackendHostCore(
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& name,
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::FilePath& sync_data_folder_path,
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool has_sync_setup_completed,
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::WeakPtr<SyncBackendHostImpl>& backend)
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : name_(name),
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_data_folder_path_(sync_data_folder_path),
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      host_(backend),
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_loop_(NULL),
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      registrar_(NULL),
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      has_sync_setup_completed_(has_sync_setup_completed),
110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      forward_protocol_events_(false),
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      forward_type_info_(false),
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      weak_ptr_factory_(this) {
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(backend.get());
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SyncBackendHostCore::~SyncBackendHostCore() {
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!sync_manager_.get());
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnSyncCycleCompleted(
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::sessions::SyncSessionSnapshot& snapshot) {
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop,
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      snapshot);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoRefreshTypes(syncer::ModelTypeSet types) {
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->RefreshTypes(types);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnControlTypesDownloadRetry() {
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::HandleControlTypesDownloadRetry);
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnInitializationComplete(
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::WeakHandle<syncer::JsBackend>& js_backend,
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        debug_info_listener,
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool success,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelTypeSet restored_types) {
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!success) {
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DoDestroySyncManager();
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_.Call(FROM_HERE,
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register for encryption related changes now. We have to do this before
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the initializing downloading control types or initializing the encryption
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // handler in order to receive notifications triggered during encryption
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // startup.
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->AddObserver(this);
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sync manager initialization is complete, so we can schedule recurring
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SaveChanges.
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_loop_->PostTask(FROM_HERE,
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       base::Bind(&SyncBackendHostCore::StartSavingChanges,
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  weak_ptr_factory_.GetWeakPtr()));
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Hang on to these for a while longer.  We're not ready to hand them back to
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the UI thread yet.
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  js_backend_ = js_backend;
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  debug_info_listener_ = debug_info_listener;
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Track whether or not sync DB and preferences were in sync.
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncBackendInitState backend_init_state;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (has_sync_setup_completed_ && !restored_types.Empty()) {
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = SETUP_COMPLETED_FOUND_RESTORED_TYPES;
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (has_sync_setup_completed_ && restored_types.Empty()) {
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = SETUP_COMPLETED_NO_RESTORED_TYPES;
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (!has_sync_setup_completed_ && restored_types.Empty()) {
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = FIRST_SETUP_NO_RESTORED_TYPES;
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else { // (!has_sync_setup_completed_ && !restored_types.Empty())
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = FIRST_SETUP_RESTORED_TYPES;
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Sync.BackendInitializeRestoreState",
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            backend_init_state,
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            SYNC_BACKEND_INIT_STATE_COUNT);
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Before proceeding any further, we need to download the control types and
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // purge any partial data (ie. data downloaded for a type that was on its way
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // to being initially synced, but didn't quite make it.).  The following
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // configure cycle will take care of this.  It depends on the registrar state
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // which we initialize below to ensure that we don't perform any downloads if
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // all control types have already completed their initial sync.
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->SetInitialTypes(restored_types);
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ConfigureReason reason =
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      restored_types.Empty() ?
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       syncer::CONFIGURE_REASON_NEW_CLIENT :
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE;
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes(
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::ControlTypes(), syncer::ModelTypeSet());
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelSafeRoutingInfo routing_info;
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->GetModelSafeRoutingInfo(&routing_info);
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SDVLOG(1) << "Control Types "
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << syncer::ModelTypeSetToString(new_control_types)
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << " added; calling ConfigureSyncer";
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelTypeSet types_to_purge =
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::Difference(syncer::ModelTypeSet::All(),
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         GetRoutingInfoTypes(routing_info));
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->ConfigureSyncer(
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reason,
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new_control_types,
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      types_to_purge,
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::ModelTypeSet(),
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::ModelTypeSet(),
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      routing_info,
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes,
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()),
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::OnControlTypesDownloadRetry,
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnConnectionStatusChange(
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ConnectionStatus status) {
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop, status);
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnPassphraseRequired(
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::PassphraseRequiredReason reason,
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const sync_pb::EncryptedData& pending_keys) {
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyPassphraseRequired, reason, pending_keys);
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnPassphraseAccepted() {
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyPassphraseAccepted);
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnBootstrapTokenUpdated(
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& bootstrap_token,
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::BootstrapTokenType type) {
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::PersistEncryptionBootstrapToken,
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             bootstrap_token,
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             type);
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnEncryptedTypesChanged(
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ModelTypeSet encrypted_types,
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool encrypt_everything) {
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NOTE: We're in a transaction.
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyEncryptedTypesChanged,
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      encrypted_types, encrypt_everything);
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnEncryptionComplete() {
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NOTE: We're in a transaction.
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyEncryptionComplete);
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnCryptographerStateChanged(
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::Cryptographer* cryptographer) {
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Do nothing.
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnPassphraseTypeChanged(
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::PassphraseType type, base::Time passphrase_time) {
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop,
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      type, passphrase_time);
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::OnCommitCountersUpdated(
307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::CommitCounters& counters) {
309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  host_.Call(
310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop,
312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      type, counters);
313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::OnUpdateCountersUpdated(
316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::UpdateCounters& counters) {
318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  host_.Call(
319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop,
321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      type, counters);
322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::OnStatusCountersUpdated(
325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::StatusCounters& counters) {
327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  host_.Call(
328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop,
330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      type, counters);
331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnActionableError(
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::SyncProtocolError& sync_error) {
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop,
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_error);
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) {
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host_.Call(
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop,
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      types);
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
352effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SyncBackendHostCore::OnProtocolEvent(
353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const syncer::ProtocolEvent& event) {
354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr.
355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (forward_protocol_events_) {
356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_ptr<syncer::ProtocolEvent> event_clone(event.Clone());
357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    host_.Call(
358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        event_clone.release());
361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoOnInvalidatorStateChange(
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::InvalidatorState state) {
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->OnInvalidatorStateChange(state);
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoOnIncomingInvalidation(
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ObjectIdInvalidationMap& invalidation_map) {
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->OnIncomingInvalidation(invalidation_map);
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoInitialize(
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<DoInitializeOptions> options) {
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!sync_loop_);
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_loop_ = options->sync_loop;
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(sync_loop_);
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Finish initializing the HttpBridgeFactory.  We do this here because
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // building the user agent may block on some platforms.
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome::VersionInfo version_info;
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  options->http_bridge_factory->Init(
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DeviceInfo::MakeUserAgentForSyncApi(version_info));
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Blow away the partial or corrupt sync data folder before doing any more
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // initialization, if necessary.
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (options->delete_sync_data_folder) {
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DeleteSyncDataFolder();
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make sure that the directory exists before initializing the backend.
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If it already exists, this will do no harm.
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!base::CreateDirectory(sync_data_folder_path_)) {
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DLOG(FATAL) << "Sync Data directory creation failed.";
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!registrar_);
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_ = options->registrar;
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(registrar_);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_);
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->AddObserver(this);
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->Init(sync_data_folder_path_,
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->event_handler,
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->service_url.host() + options->service_url.path(),
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->service_url.EffectiveIntPort(),
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->service_url.SchemeIsSecure(),
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->http_bridge_factory.Pass(),
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->workers,
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->extensions_activity,
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->registrar /* as SyncManager::ChangeDelegate */,
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->credentials,
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->invalidator_client_id,
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->restored_key_for_bootstrapping,
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->restored_keystore_key_for_bootstrapping,
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->internal_components_factory.get(),
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      &encryptor_,
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->unrecoverable_error_handler.Pass(),
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      options->report_unrecoverable_error_function,
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      &stop_syncing_signal_);
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoUpdateCredentials(
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::SyncCredentials& credentials) {
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // UpdateCredentials can be called during backend initialization, possibly
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // when backend initialization has failed but hasn't notified the UI thread
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // yet. In that case, the sync manager may have been destroyed on the sync
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // thread before this task was executed, so we do nothing.
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sync_manager_) {
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_->UpdateCredentials(credentials);
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoStartSyncing(
439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelSafeRoutingInfo& routing_info) {
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->StartSyncingNormally(routing_info);
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoSetEncryptionPassphrase(
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& passphrase,
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_explicit) {
447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase(
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      passphrase, is_explicit);
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoInitialProcessControlTypes() {
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << "Initilalizing Control Types";
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initialize encryption.
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->Init();
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Note: experiments are currently handled via SBH::AddExperimentalTypes,
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // which is called at the end of every sync cycle.
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(zea): eventually add an experiment handler and initialize it here.
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_manager_->GetUserShare()) {  // NULL in some tests.
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(1) << "Skipping initialization of DeviceInfo";
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_.Call(
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FROM_HERE,
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) {
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(ERROR) << "Failed to download control types";
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_.Call(
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FROM_HERE,
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initialize device info. This is asynchronous on some platforms, so we
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // provide a callback for when it finishes.
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  synced_device_tracker_.reset(
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new SyncedDeviceTracker(sync_manager_->GetUserShare(),
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              sync_manager_->cache_guid()));
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  synced_device_tracker_->InitLocalDeviceInfo(
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoFinishInitialProcessControlTypes,
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoFinishInitialProcessControlTypes() {
491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
492c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->ActivateDataType(syncer::DEVICE_INFO,
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               syncer::GROUP_PASSIVE,
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               synced_device_tracker_.get(),
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               sync_manager_->GetUserShare());
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop,
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      js_backend_,
502c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      debug_info_listener_,
503a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      sync_manager_->GetSyncCoreProxy());
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  js_backend_.Reset();
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  debug_info_listener_.Reset();
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoSetDecryptionPassphrase(
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& passphrase) {
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      passphrase);
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoEnableEncryptEverything() {
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::ShutdownOnUIThread() {
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This will cut short any blocking network tasks, cut short any in-progress
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // sync cycles, and prevent the creation of new blocking network tasks and new
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // sync cycles.  If there was an in-progress network request, it would have
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // had a reference to the RequestContextGetter.  This reference will be
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // dropped by the time this function returns.
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // It is safe to call this even if Sync's backend classes have not been
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // initialized yet.  Those classes will receive the message when the sync
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // thread finally getes around to constructing them.
531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stop_syncing_signal_.Signal();
532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This will drop the HttpBridgeFactory's reference to the
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // RequestContextGetter.  Once this has been called, the HttpBridgeFactory can
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // no longer be used to create new HttpBridge instances.  We can get away with
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // this because the stop_syncing_signal_ has already been signalled, which
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // guarantees that the ServerConnectionManager will no longer attempt to
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // create new connections.
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  release_request_context_signal_.Signal();
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoShutdown(bool sync_disabled) {
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // It's safe to do this even if the type was never activated.
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->DeactivateDataType(syncer::DEVICE_INFO);
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  synced_device_tracker_.reset();
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DoDestroySyncManager();
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_ = NULL;
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sync_disabled)
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DeleteSyncDataFolder();
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Reset();
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  weak_ptr_factory_.InvalidateWeakPtrs();
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoDestroySyncManager() {
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sync_manager_) {
563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DisableDirectoryTypeDebugInfoForwarding();
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    save_changes_timer_.reset();
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_->RemoveObserver(this);
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_->ShutdownOnSyncThread();
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_.reset();
568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoConfigureSyncer(
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ConfigureReason reason,
573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const DoConfigureSyncerTypes& config_types,
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelSafeRoutingInfo routing_info,
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Callback<void(syncer::ModelTypeSet,
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              syncer::ModelTypeSet)>& ready_task,
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& retry_callback) {
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->ConfigureSyncer(
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reason,
581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      config_types.to_download,
582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      config_types.to_purge,
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      config_types.to_journal,
584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      config_types.to_unapply,
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      routing_info,
586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoFinishConfigureDataTypes,
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 config_types.to_download,
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 ready_task),
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoRetryConfiguration,
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 retry_callback));
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoFinishConfigureDataTypes(
596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ModelTypeSet types_to_config,
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Callback<void(syncer::ModelTypeSet,
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              syncer::ModelTypeSet)>& ready_task) {
599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Update the enabled types for the bridge and sync manager.
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelSafeRoutingInfo routing_info;
603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->GetModelSafeRoutingInfo(&routing_info);
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info);
605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  enabled_types.RemoveAll(syncer::ProxyTypes());
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const syncer::ModelTypeSet failed_configuration_types =
608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Difference(types_to_config, sync_manager_->InitialSyncEndedTypes());
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const syncer::ModelTypeSet succeeded_configuration_types =
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Difference(types_to_config, failed_configuration_types);
611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop,
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             enabled_types,
614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             succeeded_configuration_types,
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             failed_configuration_types,
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             ready_task);
617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoRetryConfiguration(
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& retry_callback) {
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::RetryConfigurationOnFrontendLoop,
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             retry_callback);
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
627e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding() {
628effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
629e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  forward_protocol_events_ = true;
630e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
631e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (sync_manager_) {
632e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Grab our own copy of the buffered events.
633e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // The buffer is not modified by this operation.
634e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    std::vector<syncer::ProtocolEvent*> buffered_events;
635e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    sync_manager_->GetBufferedProtocolEvents().release(&buffered_events);
636e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
637e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Send them all over the fence to the host.
638e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    for (std::vector<syncer::ProtocolEvent*>::iterator it =
639e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         buffered_events.begin(); it != buffered_events.end(); ++it) {
640e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // TODO(rlarocque): Make it explicit that host_ takes ownership.
641e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_.Call(
642e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          FROM_HERE,
643e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
644e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          *it);
645e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
646e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
647e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
648e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
649e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid SyncBackendHostCore::DisableProtocolEventForwarding() {
650e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  forward_protocol_events_ = false;
651effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
652effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
653010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() {
654010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(sync_manager_);
655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  forward_type_info_ = true;
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
658010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
659010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this);
660010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  sync_manager_->RequestEmitDebugInfo();
661010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
662010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
663010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() {
664010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(sync_manager_);
665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!forward_type_info_)
667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  forward_type_info_ = false;
670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
671010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
672010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this);
673010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
674010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DeleteSyncDataFolder() {
676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (base::DirectoryExists(sync_data_folder_path_)) {
678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!base::DeleteFile(sync_data_folder_path_, true))
679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SLOG(DFATAL) << "Could not delete the Sync Data folder.";
680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
683c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SyncBackendHostCore::GetAllNodesForTypes(
684c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    syncer::ModelTypeSet types,
685c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_refptr<base::SequencedTaskRunner> task_runner,
686c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::Callback<void(const std::vector<syncer::ModelType>& type,
687c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                        ScopedVector<base::ListValue>)> callback) {
688c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<syncer::ModelType> types_vector;
689c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScopedVector<base::ListValue> node_lists;
690c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
691c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  syncer::ModelSafeRoutingInfo routes;
692c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  registrar_->GetModelSafeRoutingInfo(&routes);
693c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routes);
694c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
695c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
696c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    types_vector.push_back(it.Get());
697c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!enabled_types.Has(it.Get())) {
698c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      node_lists.push_back(new base::ListValue());
699c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    } else {
700c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      node_lists.push_back(
701c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          sync_manager_->GetAllNodesForType(it.Get()).release());
702c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
703c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
704c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
705c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_runner->PostTask(
706c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      FROM_HERE,
707c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(callback, types_vector, base::Passed(&node_lists)));
708c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
709c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::StartSavingChanges() {
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We may already be shut down.
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!save_changes_timer_.get());
716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  save_changes_timer_.reset(new base::RepeatingTimer<SyncBackendHostCore>());
717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  save_changes_timer_->Start(FROM_HERE,
718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds),
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this, &SyncBackendHostCore::SaveChanges);
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::SaveChanges() {
723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->SaveChanges();
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace browser_sync
728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
729