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)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/sync/glue/invalidation_adapter.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/sync/glue/local_device_info_provider_impl.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync/glue/sync_backend_registrar.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/chrome_version_info.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/invalidation/invalidation_util.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/invalidation/object_id_invalidation_map.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"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/commit_counters.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/status_counters.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/sessions/sync_session_snapshot.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "sync/internal_api/public/sessions/update_counters.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/internal_api/public/sync_context_proxy.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/sync_manager.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "sync/internal_api/public/sync_manager_factory.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "url/gurl.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Helper macros to log with the syncer thread name; useful when there
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// are multiple syncers involved.
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define SLOG(severity) LOG(severity) << name_ << ": "
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": "
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const int kSaveChangesIntervalSeconds = 10;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace syncer {
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class InternalComponentsFactory;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace syncer
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Enums for UMAs.
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)enum SyncBackendInitState {
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SETUP_COMPLETED_FOUND_RESTORED_TYPES = 0,
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SETUP_COMPLETED_NO_RESTORED_TYPES,
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FIRST_SETUP_NO_RESTORED_TYPES,
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FIRST_SETUP_RESTORED_TYPES,
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SYNC_BACKEND_INIT_STATE_COUNT
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace browser_sync {
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoInitializeOptions::DoInitializeOptions(
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::MessageLoop* sync_loop,
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncBackendRegistrar* registrar,
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelSafeRoutingInfo& routing_info,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<scoped_refptr<syncer::ModelSafeWorker> >& workers,
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity,
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& service_url,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::HttpPostProviderFactory> http_bridge_factory,
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::SyncCredentials& credentials,
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& invalidator_client_id,
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool delete_sync_data_folder,
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& restored_key_for_bootstrapping,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& restored_keystore_key_for_bootstrapping,
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::InternalComponentsFactory> internal_components_factory,
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ReportUnrecoverableErrorFunction
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        report_unrecoverable_error_function)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : sync_loop(sync_loop),
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      registrar(registrar),
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      routing_info(routing_info),
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      workers(workers),
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extensions_activity(extensions_activity),
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      event_handler(event_handler),
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      service_url(service_url),
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      http_bridge_factory(http_bridge_factory.Pass()),
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      credentials(credentials),
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      invalidator_client_id(invalidator_client_id),
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_manager_factory(sync_manager_factory.Pass()),
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      delete_sync_data_folder(delete_sync_data_folder),
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      restored_key_for_bootstrapping(restored_key_for_bootstrapping),
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      restored_keystore_key_for_bootstrapping(
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          restored_keystore_key_for_bootstrapping),
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      internal_components_factory(internal_components_factory.Pass()),
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      report_unrecoverable_error_function(report_unrecoverable_error_function) {
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoInitializeOptions::~DoInitializeOptions() {}
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoConfigureSyncerTypes::DoConfigureSyncerTypes() {}
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DoConfigureSyncerTypes::~DoConfigureSyncerTypes() {}
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SyncBackendHostCore::SyncBackendHostCore(
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& name,
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::FilePath& sync_data_folder_path,
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool has_sync_setup_completed,
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::WeakPtr<SyncBackendHostImpl>& backend)
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : name_(name),
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_data_folder_path_(sync_data_folder_path),
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      host_(backend),
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_loop_(NULL),
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      registrar_(NULL),
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      has_sync_setup_completed_(has_sync_setup_completed),
111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      forward_protocol_events_(false),
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      forward_type_info_(false),
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      weak_ptr_factory_(this) {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(backend.get());
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SyncBackendHostCore::~SyncBackendHostCore() {
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!sync_manager_.get());
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnSyncCycleCompleted(
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::sessions::SyncSessionSnapshot& snapshot) {
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop,
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      snapshot);
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoRefreshTypes(syncer::ModelTypeSet types) {
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->RefreshTypes(types);
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnControlTypesDownloadRetry() {
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::HandleControlTypesDownloadRetry);
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnInitializationComplete(
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::WeakHandle<syncer::JsBackend>& js_backend,
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        debug_info_listener,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool success,
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelTypeSet restored_types) {
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!success) {
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DoDestroySyncManager(syncer::STOP_SYNC);
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_.Call(FROM_HERE,
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register for encryption related changes now. We have to do this before
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the initializing downloading control types or initializing the encryption
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // handler in order to receive notifications triggered during encryption
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // startup.
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->AddObserver(this);
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sync manager initialization is complete, so we can schedule recurring
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SaveChanges.
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_loop_->PostTask(FROM_HERE,
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       base::Bind(&SyncBackendHostCore::StartSavingChanges,
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  weak_ptr_factory_.GetWeakPtr()));
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Hang on to these for a while longer.  We're not ready to hand them back to
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the UI thread yet.
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  js_backend_ = js_backend;
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  debug_info_listener_ = debug_info_listener;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Track whether or not sync DB and preferences were in sync.
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncBackendInitState backend_init_state;
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (has_sync_setup_completed_ && !restored_types.Empty()) {
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = SETUP_COMPLETED_FOUND_RESTORED_TYPES;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (has_sync_setup_completed_ && restored_types.Empty()) {
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = SETUP_COMPLETED_NO_RESTORED_TYPES;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (!has_sync_setup_completed_ && restored_types.Empty()) {
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = FIRST_SETUP_NO_RESTORED_TYPES;
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else { // (!has_sync_setup_completed_ && !restored_types.Empty())
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    backend_init_state = FIRST_SETUP_RESTORED_TYPES;
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Sync.BackendInitializeRestoreState",
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            backend_init_state,
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            SYNC_BACKEND_INIT_STATE_COUNT);
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Before proceeding any further, we need to download the control types and
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // purge any partial data (ie. data downloaded for a type that was on its way
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // to being initially synced, but didn't quite make it.).  The following
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // configure cycle will take care of this.  It depends on the registrar state
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // which we initialize below to ensure that we don't perform any downloads if
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // all control types have already completed their initial sync.
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->SetInitialTypes(restored_types);
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ConfigureReason reason =
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      restored_types.Empty() ?
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       syncer::CONFIGURE_REASON_NEW_CLIENT :
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE;
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes(
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::ControlTypes(), syncer::ModelTypeSet());
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelSafeRoutingInfo routing_info;
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->GetModelSafeRoutingInfo(&routing_info);
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SDVLOG(1) << "Control Types "
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << syncer::ModelTypeSetToString(new_control_types)
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << " added; calling ConfigureSyncer";
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelTypeSet types_to_purge =
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::Difference(syncer::ModelTypeSet::All(),
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         GetRoutingInfoTypes(routing_info));
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->ConfigureSyncer(
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reason,
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new_control_types,
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      types_to_purge,
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::ModelTypeSet(),
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      syncer::ModelTypeSet(),
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      routing_info,
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes,
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()),
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::OnControlTypesDownloadRetry,
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnConnectionStatusChange(
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ConnectionStatus status) {
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop, status);
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnPassphraseRequired(
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::PassphraseRequiredReason reason,
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const sync_pb::EncryptedData& pending_keys) {
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyPassphraseRequired, reason, pending_keys);
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnPassphraseAccepted() {
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyPassphraseAccepted);
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnBootstrapTokenUpdated(
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& bootstrap_token,
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::BootstrapTokenType type) {
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::PersistEncryptionBootstrapToken,
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             bootstrap_token,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             type);
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnEncryptedTypesChanged(
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ModelTypeSet encrypted_types,
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool encrypt_everything) {
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NOTE: We're in a transaction.
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyEncryptedTypesChanged,
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      encrypted_types, encrypt_everything);
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnEncryptionComplete() {
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NOTE: We're in a transaction.
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::NotifyEncryptionComplete);
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnCryptographerStateChanged(
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::Cryptographer* cryptographer) {
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Do nothing.
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnPassphraseTypeChanged(
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::PassphraseType type, base::Time passphrase_time) {
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop,
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      type, passphrase_time);
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::OnCommitCountersUpdated(
308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::CommitCounters& counters) {
310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  host_.Call(
311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop,
313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      type, counters);
314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::OnUpdateCountersUpdated(
317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::UpdateCounters& counters) {
319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  host_.Call(
320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop,
322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      type, counters);
323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::OnStatusCountersUpdated(
326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    syncer::ModelType type,
327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const syncer::StatusCounters& counters) {
328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  host_.Call(
329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop,
331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      type, counters);
332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::OnActionableError(
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::SyncProtocolError& sync_error) {
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop,
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sync_error);
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) {
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host_.Call(
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop,
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      types);
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SyncBackendHostCore::OnProtocolEvent(
354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const syncer::ProtocolEvent& event) {
355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr.
356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (forward_protocol_events_) {
357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_ptr<syncer::ProtocolEvent> event_clone(event.Clone());
358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    host_.Call(
359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        event_clone.release());
362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoOnInvalidatorStateChange(
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::InvalidatorState state) {
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sync_manager_->SetInvalidatorEnabled(state == syncer::INVALIDATIONS_ENABLED);
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoOnIncomingInvalidation(
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ObjectIdInvalidationMap& invalidation_map) {
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (syncer::ObjectIdSet::const_iterator ids_it = ids.begin();
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ids_it != ids.end();
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++ids_it) {
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syncer::ModelType type;
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!NotificationTypeToRealModelType(ids_it->name(), &type)) {
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DLOG(WARNING) << "Notification has invalid id: "
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    << syncer::ObjectIdToString(*ids_it);
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else {
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      syncer::SingleObjectInvalidationSet invalidation_set =
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          invalidation_map.ForObject(*ids_it);
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      for (syncer::SingleObjectInvalidationSet::const_iterator inv_it =
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               invalidation_set.begin();
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           inv_it != invalidation_set.end();
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           ++inv_it) {
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        scoped_ptr<syncer::InvalidationInterface> inv_adapter(
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            new InvalidationAdapter(*inv_it));
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        sync_manager_->OnIncomingInvalidation(type, inv_adapter.Pass());
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoInitialize(
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<DoInitializeOptions> options) {
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!sync_loop_);
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_loop_ = options->sync_loop;
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(sync_loop_);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Finish initializing the HttpBridgeFactory.  We do this here because
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // building the user agent may block on some platforms.
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome::VersionInfo version_info;
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  options->http_bridge_factory->Init(
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LocalDeviceInfoProviderImpl::MakeUserAgentForSyncApi(version_info));
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Blow away the partial or corrupt sync data folder before doing any more
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // initialization, if necessary.
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (options->delete_sync_data_folder) {
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DeleteSyncDataFolder();
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make sure that the directory exists before initializing the backend.
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If it already exists, this will do no harm.
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!base::CreateDirectory(sync_data_folder_path_)) {
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DLOG(FATAL) << "Sync Data directory creation failed.";
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!registrar_);
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_ = options->registrar;
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(registrar_);
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_);
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->AddObserver(this);
4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  syncer::SyncManager::InitArgs args;
4306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.database_location = sync_data_folder_path_;
4316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.event_handler = options->event_handler;
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.service_url = options->service_url;
4336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.post_factory = options->http_bridge_factory.Pass();
4346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.workers = options->workers;
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  args.extensions_activity = options->extensions_activity.get();
4366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.change_delegate = options->registrar;  // as SyncManager::ChangeDelegate
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.credentials = options->credentials;
4386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.invalidator_client_id = options->invalidator_client_id;
4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.restored_key_for_bootstrapping = options->restored_key_for_bootstrapping;
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.restored_keystore_key_for_bootstrapping =
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      options->restored_keystore_key_for_bootstrapping;
4426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.internal_components_factory =
4436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      options->internal_components_factory.Pass();
4446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.encryptor = &encryptor_;
4456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.unrecoverable_error_handler =
4466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      options->unrecoverable_error_handler.Pass();
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.report_unrecoverable_error_function =
4486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      options->report_unrecoverable_error_function;
4496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  args.cancelation_signal = &stop_syncing_signal_;
4506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sync_manager_->Init(&args);
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoUpdateCredentials(
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::SyncCredentials& credentials) {
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // UpdateCredentials can be called during backend initialization, possibly
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // when backend initialization has failed but hasn't notified the UI thread
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // yet. In that case, the sync manager may have been destroyed on the sync
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // thread before this task was executed, so we do nothing.
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sync_manager_) {
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_->UpdateCredentials(credentials);
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoStartSyncing(
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelSafeRoutingInfo& routing_info) {
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->StartSyncingNormally(routing_info);
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoSetEncryptionPassphrase(
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& passphrase,
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_explicit) {
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase(
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      passphrase, is_explicit);
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoInitialProcessControlTypes() {
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << "Initilalizing Control Types";
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initialize encryption.
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->Init();
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Note: experiments are currently handled via SBH::AddExperimentalTypes,
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // which is called at the end of every sync cycle.
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(zea): eventually add an experiment handler and initialize it here.
490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_manager_->GetUserShare()) {  // NULL in some tests.
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(1) << "Skipping initialization of DeviceInfo";
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_.Call(
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FROM_HERE,
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) {
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(ERROR) << "Failed to download control types";
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_.Call(
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FROM_HERE,
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  host_.Call(FROM_HERE,
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             &SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop,
509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             js_backend_,
510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             debug_info_listener_,
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)             sync_manager_->GetSyncContextProxy(),
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)             sync_manager_->cache_guid());
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  js_backend_.Reset();
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  debug_info_listener_.Reset();
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoSetDecryptionPassphrase(
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& passphrase) {
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      passphrase);
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoEnableEncryptEverything() {
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::ShutdownOnUIThread() {
531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This will cut short any blocking network tasks, cut short any in-progress
532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // sync cycles, and prevent the creation of new blocking network tasks and new
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // sync cycles.  If there was an in-progress network request, it would have
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // had a reference to the RequestContextGetter.  This reference will be
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // dropped by the time this function returns.
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // It is safe to call this even if Sync's backend classes have not been
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // initialized yet.  Those classes will receive the message when the sync
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // thread finally getes around to constructing them.
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stop_syncing_signal_.Signal();
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This will drop the HttpBridgeFactory's reference to the
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // RequestContextGetter.  Once this has been called, the HttpBridgeFactory can
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // no longer be used to create new HttpBridge instances.  We can get away with
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // this because the stop_syncing_signal_ has already been signalled, which
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // guarantees that the ServerConnectionManager will no longer attempt to
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // create new connections.
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  release_request_context_signal_.Signal();
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SyncBackendHostCore::DoShutdown(syncer::ShutdownReason reason) {
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DoDestroySyncManager(reason);
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_ = NULL;
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (reason == syncer::DISABLE_SYNC)
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DeleteSyncDataFolder();
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Reset();
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  weak_ptr_factory_.InvalidateWeakPtrs();
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SyncBackendHostCore::DoDestroySyncManager(syncer::ShutdownReason reason) {
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sync_manager_) {
568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DisableDirectoryTypeDebugInfoForwarding();
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    save_changes_timer_.reset();
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_->RemoveObserver(this);
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sync_manager_->ShutdownOnSyncThread(reason);
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_manager_.reset();
573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoConfigureSyncer(
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ConfigureReason reason,
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const DoConfigureSyncerTypes& config_types,
579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::ModelSafeRoutingInfo routing_info,
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Callback<void(syncer::ModelTypeSet,
581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              syncer::ModelTypeSet)>& ready_task,
582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& retry_callback) {
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
5846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!ready_task.is_null());
5856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!retry_callback.is_null());
5866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::Closure chained_ready_task(
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoFinishConfigureDataTypes,
588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 config_types.to_download,
5906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                 ready_task));
5916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::Closure chained_retry_task(
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&SyncBackendHostCore::DoRetryConfiguration,
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 retry_callback));
5956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sync_manager_->ConfigureSyncer(reason,
5966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 config_types.to_download,
5976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 config_types.to_purge,
5986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 config_types.to_journal,
5996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 config_types.to_unapply,
6006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 routing_info,
6016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 chained_ready_task,
6026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 chained_retry_task);
603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoFinishConfigureDataTypes(
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::ModelTypeSet types_to_config,
607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Callback<void(syncer::ModelTypeSet,
608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              syncer::ModelTypeSet)>& ready_task) {
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Update the enabled types for the bridge and sync manager.
612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelSafeRoutingInfo routing_info;
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registrar_->GetModelSafeRoutingInfo(&routing_info);
614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info);
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  enabled_types.RemoveAll(syncer::ProxyTypes());
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const syncer::ModelTypeSet failed_configuration_types =
618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Difference(types_to_config, sync_manager_->InitialSyncEndedTypes());
619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const syncer::ModelTypeSet succeeded_configuration_types =
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Difference(types_to_config, failed_configuration_types);
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop,
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             enabled_types,
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             succeeded_configuration_types,
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             failed_configuration_types,
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             ready_task);
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DoRetryConfiguration(
630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& retry_callback) {
631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_.Call(FROM_HERE,
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             &SyncBackendHostImpl::RetryConfigurationOnFrontendLoop,
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             retry_callback);
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
637e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding() {
638effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
639e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  forward_protocol_events_ = true;
640e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
641e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (sync_manager_) {
642e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Grab our own copy of the buffered events.
643e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // The buffer is not modified by this operation.
644e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    std::vector<syncer::ProtocolEvent*> buffered_events;
645e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    sync_manager_->GetBufferedProtocolEvents().release(&buffered_events);
646e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
647e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Send them all over the fence to the host.
648e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    for (std::vector<syncer::ProtocolEvent*>::iterator it =
649e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         buffered_events.begin(); it != buffered_events.end(); ++it) {
650e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // TODO(rlarocque): Make it explicit that host_ takes ownership.
651e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_.Call(
652e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          FROM_HERE,
653e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
654e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          *it);
655e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
656e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
657e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
658e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
659e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid SyncBackendHostCore::DisableProtocolEventForwarding() {
660e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  forward_protocol_events_ = false;
661effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
662effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
663010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() {
664010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(sync_manager_);
665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  forward_type_info_ = true;
667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
668010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
669010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this);
670010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  sync_manager_->RequestEmitDebugInfo();
671010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
672010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
673010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() {
674010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(sync_manager_);
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!forward_type_info_)
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  forward_type_info_ = false;
680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
681010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
682010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this);
683010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
684010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::DeleteSyncDataFolder() {
686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (base::DirectoryExists(sync_data_folder_path_)) {
688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!base::DeleteFile(sync_data_folder_path_, true))
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SLOG(DFATAL) << "Could not delete the Sync Data folder.";
690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
693c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SyncBackendHostCore::GetAllNodesForTypes(
694c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    syncer::ModelTypeSet types,
695c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_refptr<base::SequencedTaskRunner> task_runner,
696c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::Callback<void(const std::vector<syncer::ModelType>& type,
697c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                        ScopedVector<base::ListValue>)> callback) {
698c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<syncer::ModelType> types_vector;
699c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScopedVector<base::ListValue> node_lists;
700c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
701c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  syncer::ModelSafeRoutingInfo routes;
702c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  registrar_->GetModelSafeRoutingInfo(&routes);
703c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routes);
704c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
705c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
706c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    types_vector.push_back(it.Get());
707c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!enabled_types.Has(it.Get())) {
708c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      node_lists.push_back(new base::ListValue());
709c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    } else {
710c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      node_lists.push_back(
711c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          sync_manager_->GetAllNodesForType(it.Get()).release());
712c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
713c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
714c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
715c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_runner->PostTask(
716c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      FROM_HERE,
717c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(callback, types_vector, base::Passed(&node_lists)));
718c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
719c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::StartSavingChanges() {
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We may already be shut down.
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!sync_loop_)
723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!save_changes_timer_.get());
726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  save_changes_timer_.reset(new base::RepeatingTimer<SyncBackendHostCore>());
727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  save_changes_timer_->Start(FROM_HERE,
728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds),
729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this, &SyncBackendHostCore::SaveChanges);
730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyncBackendHostCore::SaveChanges() {
733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  sync_manager_->SaveChanges();
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace browser_sync
738