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