1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "build/build_config.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/compiler_specific.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/threading/thread_restrictions.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/net/gaia/token_service.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncapi.h"
1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/sync/glue/autofill_model_associator.h"
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/change_processor.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/database_model_worker.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/history_model_worker.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/http_bridge.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/password_model_worker.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/glue/sync_backend_host.h"
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/js_arg_list.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/notifier/sync_notifier.h"
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/notifier/sync_notifier_factory.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/session_state.h"
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// TODO(tim): Remove this! We should have a syncapi pass-thru instead.
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/sync/syncable/directory_manager.h"  // Cryptographer.
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/sync/syncable/model_type.h"
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/syncable/nigori_util.h"
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/gaia_constants.h"
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/pref_names.h"
39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "googleurl/src/gurl.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kSaveChangesIntervalSeconds = 10;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const FilePath::CharType kSyncDataFolderName[] =
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FILE_PATH_LITERAL("Sync Data");
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::DataTypeController;
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing sync_notifier::SyncNotifierFactory;
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricktypedef TokenService::TokenAvailableDetails TokenAvailableDetails;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef GoogleServiceAuthError AuthError;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing sessions::SyncSessionSnapshot;
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing sync_api::SyncCredentials;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSyncBackendHost::SyncBackendHost(Profile* profile)
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : core_(new Core(ALLOW_THIS_IN_INITIALIZER_LIST(this))),
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      core_thread_("Chrome_SyncCoreThread"),
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      frontend_loop_(MessageLoop::current()),
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_(profile),
6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      frontend_(NULL),
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      sync_data_folder_path_(
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          profile_->GetPath().Append(kSyncDataFolderName)),
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      last_auth_error_(AuthError::None()),
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      syncapi_initialized_(false) {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::SyncBackendHost()
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : core_thread_("Chrome_SyncCoreThread"),
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      frontend_loop_(MessageLoop::current()),
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      profile_(NULL),
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      frontend_(NULL),
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      last_auth_error_(AuthError::None()),
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      syncapi_initialized_(false) {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::~SyncBackendHost() {
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor.";
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(registrar_.workers.empty());
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Initialize(
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SyncFrontend* frontend,
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& sync_service_url,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const syncable::ModelTypeSet& types,
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* baseline_context_getter,
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const SyncCredentials& credentials,
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool delete_sync_data_folder) {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!core_thread_.Start())
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  frontend_ = frontend;
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(frontend);
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a worker for the UI thread and route bookmark changes to it.
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(tim): Pull this into a method to reuse.  For now we don't even
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // need to lock because we init before the syncapi exists and we tear down
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // after the syncapi is destroyed.  Make sure to NULL-check workers_ indices
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // when a new type is synced as the worker may already exist and you just
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // need to update routing_info_.
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_DB] = new DatabaseModelWorker();
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.workers[GROUP_UI] = new UIModelWorker();
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_PASSIVE] = new ModelSafeWorker();
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (CommandLine::ForCurrentProcess()->HasSwitch(
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switches::kEnableSyncTypedUrls) || types.count(syncable::TYPED_URLS)) {
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // TODO(tim): Bug 53916.  HistoryModelWorker crashes, so avoid adding it
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // unless specifically requested until bug is fixed.
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    registrar_.workers[GROUP_HISTORY] =
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new HistoryModelWorker(
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            profile_->GetHistoryService(Profile::IMPLICIT_ACCESS));
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Any datatypes that we want the syncer to pull down must
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be in the routing_info map.  We set them to group passive, meaning that
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // updates will be applied, but not dispatched to the UI thread yet.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (syncable::ModelTypeSet::const_iterator it = types.begin();
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      it != types.end(); ++it) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.routing_info[(*it)] = GROUP_PASSIVE;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  PasswordStore* password_store =
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      profile_->GetPasswordStore(Profile::IMPLICIT_ACCESS);
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (password_store) {
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    registrar_.workers[GROUP_PASSWORD] =
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new PasswordModelWorker(password_store);
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG_IF(WARNING, types.count(syncable::PASSWORDS) > 0) << "Password store "
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        << "not initialized, cannot sync passwords";
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    registrar_.routing_info.erase(syncable::PASSWORDS);
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Nigori is populated by default now.
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  registrar_.routing_info[syncable::NIGORI] = GROUP_PASSIVE;
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(akalin): Create SyncNotifier here and pass it in as part of
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DoInitializeOptions.
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  core_->CreateSyncNotifier(baseline_context_getter);
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  InitCore(Core::DoInitializeOptions(
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      sync_service_url,
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      MakeHttpBridgeFactory(baseline_context_getter),
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      credentials,
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      delete_sync_data_folder,
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      RestoreEncryptionBootstrapToken(),
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      false));
1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::PersistEncryptionBootstrapToken(
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& token) {
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  PrefService* prefs = profile_->GetPrefs();
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  prefs->SetString(prefs::kEncryptionBootstrapToken, token);
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  prefs->ScheduleSavePersistentPrefs();
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string SyncBackendHost::RestoreEncryptionBootstrapToken() {
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  PrefService* prefs = profile_->GetPrefs();
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string token = prefs->GetString(prefs::kEncryptionBootstrapToken);
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return token;
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool SyncBackendHost::IsNigoriEnabled() const {
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(registrar_lock_);
169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Note that NIGORI is only ever added/removed from routing_info once,
170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // during initialization / first configuration, so there is no real 'race'
171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // possible here or possibility of stale return value.
172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return registrar_.routing_info.find(syncable::NIGORI) !=
173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      registrar_.routing_info.end();
174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool SyncBackendHost::IsUsingExplicitPassphrase() {
1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return IsNigoriEnabled() && syncapi_initialized_ &&
1784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      core_->syncapi()->InitialSyncEndedForAllEnabledTypes() &&
1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      core_->syncapi()->IsUsingExplicitPassphrase();
1804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool SyncBackendHost::IsCryptographerReady(
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const sync_api::BaseTransaction* trans) const {
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return syncapi_initialized_ && trans->GetCryptographer()->is_ready();
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenJsBackend* SyncBackendHost::GetJsBackend() {
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (syncapi_initialized_) {
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return core_.get();
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NOTREACHED();
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return NULL;
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricksync_api::HttpPostProviderFactory* SyncBackendHost::MakeHttpBridgeFactory(
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* getter) {
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return new HttpBridgeFactory(getter);
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::InitCore(const Core::DoInitializeOptions& options) {
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  core_thread_.message_loop()->PostTask(FROM_HERE,
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoInitialize,
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        options));
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) {
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  core_thread_.message_loop()->PostTask(FROM_HERE,
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NewRunnableMethod(core_.get(),
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &SyncBackendHost::Core::DoUpdateCredentials,
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        credentials));
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::StartSyncingWithServer() {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  core_thread_.message_loop()->PostTask(FROM_HERE,
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoStartSyncing));
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid SyncBackendHost::SetPassphrase(const std::string& passphrase,
2204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                    bool is_explicit) {
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!IsNigoriEnabled()) {
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    LOG(WARNING) << "Silently dropping SetPassphrase request.";
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This should only be called by the frontend.
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_EQ(MessageLoop::current(), frontend_loop_);
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (core_->processing_passphrase()) {
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    VLOG(1) << "Attempted to call SetPassphrase while already waiting for "
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            << " result from previous SetPassphrase call. Silently dropping.";
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  core_->set_processing_passphrase();
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // If encryption is enabled and we've got a SetPassphrase
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  core_thread_.message_loop()->PostTask(FROM_HERE,
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoSetPassphrase,
2384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                        passphrase, is_explicit));
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Shutdown(bool sync_disabled) {
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Thread shutdown should occur in the following order:
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - SyncerThread
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - CoreThread
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - UI Thread (stops some time after we return from this call).
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (core_thread_.IsRunning()) {  // Not running in tests.
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    core_thread_.message_loop()->PostTask(FROM_HERE,
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(core_.get(),
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          &SyncBackendHost::Core::DoShutdown,
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          sync_disabled));
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Before joining the core_thread_, we wait for the UIModelWorker to
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // give us the green light that it is not depending on the frontend_loop_ to
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // process any more tasks. Stop() blocks until this termination condition
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is true.
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ui_worker())
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_worker()->Stop();
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Stop will return once the thread exits, which will be after DoShutdown
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // runs. DoShutdown needs to run from core_thread_ because the sync backend
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // requires any thread that opened sqlite handles to relinquish them
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // personally. We need to join threads, because otherwise the main Chrome
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // thread (ui loop) can exit before DoShutdown finishes, at which point
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // virtually anything the sync backend does (or the post-back to
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // frontend_loop_ by our Core) will epically fail because the CRT won't be
26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // initialized.
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Since we are blocking the UI thread here, we need to turn ourselves in
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // with the ThreadRestriction police.  For sentencing and how we plan to fix
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // this, see bug 19757.
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  {
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::ThreadRestrictions::ScopedAllowIO allow_io;
27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    core_thread_.Stop();
27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.routing_info.clear();
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_DB] = NULL;
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_HISTORY] = NULL;
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_UI] = NULL;
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_PASSIVE] = NULL;
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers[GROUP_PASSWORD] = NULL;
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers.erase(GROUP_DB);
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers.erase(GROUP_HISTORY);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers.erase(GROUP_UI);
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers.erase(GROUP_PASSIVE);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.workers.erase(GROUP_PASSWORD);
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  frontend_ = NULL;
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  core_ = NULL;  // Releases reference to core_.
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsensyncable::AutofillMigrationState
29221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SyncBackendHost::GetAutofillMigrationState() {
29321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return core_->syncapi()->GetAutofillMigrationState();
29421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
29621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SyncBackendHost::SetAutofillMigrationState(
29721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    syncable::AutofillMigrationState state) {
29821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return core_->syncapi()->SetAutofillMigrationState(state);
29921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
30021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
30121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsensyncable::AutofillMigrationDebugInfo
30221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SyncBackendHost::GetAutofillMigrationDebugInfo() {
30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return core_->syncapi()->GetAutofillMigrationDebugInfo();
30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SyncBackendHost::SetAutofillMigrationDebugInfo(
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set,
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const syncable::AutofillMigrationDebugInfo& info) {
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return core_->syncapi()->SetAutofillMigrationDebugInfo(property_to_set, info);
31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SyncBackendHost::ConfigureAutofillMigration() {
31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (GetAutofillMigrationState() == syncable::NOT_DETERMINED) {
31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::ReadTransaction trans(GetUserShare());
31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    sync_api::ReadNode autofil_root_node(&trans);
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Check for the presence of autofill node.
31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!autofil_root_node.InitByTagLookup(browser_sync::kAutofillTag)) {
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        SetAutofillMigrationState(syncable::INSUFFICIENT_INFO_TO_DETERMINE);
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Check for children under autofill node.
32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (autofil_root_node.GetFirstChildId() == static_cast<int64>(0)) {
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SetAutofillMigrationState(syncable::INSUFFICIENT_INFO_TO_DETERMINE);
32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    sync_api::ReadNode autofill_profile_root_node(&trans);
33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Check for the presence of autofill profile root node.
33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!autofill_profile_root_node.InitByTagLookup(
33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen       browser_sync::kAutofillProfileTag)) {
33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SetAutofillMigrationState(syncable::NOT_MIGRATED);
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // If our state is not determined then we should not have the autofill
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // profile node.
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(false);
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // just set it as not migrated.
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SetAutofillMigrationState(syncable::NOT_MIGRATED);
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSyncBackendHost::PendingConfigureDataTypesState::
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenPendingConfigureDataTypesState() : deleted_type(false) {}
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSyncBackendHost::PendingConfigureDataTypesState::
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen~PendingConfigureDataTypesState() {}
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSyncBackendHost::PendingConfigureDataTypesState*
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SyncBackendHost::MakePendingConfigModeState(
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        const DataTypeController::TypeMap& data_type_controllers,
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        const syncable::ModelTypeSet& types,
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        CancelableTask* ready_task,
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ModelSafeRoutingInfo* routing_info) {
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PendingConfigureDataTypesState* state = new PendingConfigureDataTypesState();
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (DataTypeController::TypeMap::const_iterator it =
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           data_type_controllers.begin();
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       it != data_type_controllers.end(); ++it) {
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncable::ModelType type = it->first;
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If a type is not specified, remove it from the routing_info.
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (types.count(type) == 0) {
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      state->deleted_type = true;
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      routing_info->erase(type);
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Add a newly specified data type as GROUP_PASSIVE into the
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // routing_info, if it does not already exist.
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (routing_info->count(type) == 0) {
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        (*routing_info)[type] = GROUP_PASSIVE;
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        state->added_types.set(type);
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state->ready_task.reset(ready_task);
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state->initial_types = types;
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return state;
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::ConfigureDataTypes(
38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const DataTypeController::TypeMap& data_type_controllers,
38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const syncable::ModelTypeSet& types,
38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    CancelableTask* ready_task) {
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only one configure is allowed at a time.
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(!pending_config_mode_state_.get());
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(!pending_download_state_.get());
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(syncapi_initialized_);
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (types.count(syncable::AUTOFILL_PROFILE) != 0) {
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ConfigureAutofillMigration();
39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  {
39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock lock(registrar_lock_);
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    pending_config_mode_state_.reset(
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        MakePendingConfigModeState(data_type_controllers, types, ready_task,
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   &registrar_.routing_info));
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StartConfiguration(NewCallback(core_.get(),
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &SyncBackendHost::Core::FinishConfigureDataTypes));
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::StartConfiguration(Callback0::Type* callback) {
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Put syncer in the config mode. DTM will put us in normal mode once it is.
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // done. This is to ensure we dont do a normal sync when we are doing model
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // association.
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  core_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    core_.get(),&SyncBackendHost::Core::DoStartConfiguration, callback));
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() {
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK_EQ(MessageLoop::current(), frontend_loop_);
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Nudge the syncer. This is necessary for both datatype addition/deletion.
420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  //
421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Deletions need a nudge in order to ensure the deletion occurs in a timely
422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // manner (see issue 56416).
423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  //
424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // In the case of additions, on the next sync cycle, the syncer should
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notice that the routing info has changed and start the process of
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // downloading updates for newly added data types.  Once this is
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // complete, the configure_state_.ready_task_ is run via an
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // OnInitializationComplete notification.
429dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (pending_config_mode_state_->deleted_type) {
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    core_thread_.message_loop()->PostTask(FROM_HERE,
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(core_.get(),
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &SyncBackendHost::Core::DeferNudgeForCleanup));
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (pending_config_mode_state_->added_types.none() &&
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !core_->syncapi()->InitialSyncEndedForAllEnabledTypes()) {
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(WARNING) << "No new types, but initial sync not finished."
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 << "Possible sync db corruption / removal.";
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // TODO(tim): Log / UMA / count this somehow?
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // TODO(tim): If no added types, we could (should?) config only for
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // types that are needed... but this is a rare corruption edge case or
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // implies the user mucked around with their syncdb, so for now do all.
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    pending_config_mode_state_->added_types =
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        syncable::ModelTypeBitSetFromSet(
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            pending_config_mode_state_->initial_types);
447dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If we've added types, we always want to request a nudge/config (even if
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the initial sync is ended), in case we could not decrypt the data.
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (pending_config_mode_state_->added_types.none()) {
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // No new types - just notify the caller that the types are available.
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    pending_config_mode_state_->ready_task->Run();
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    pending_download_state_.reset(pending_config_mode_state_.release());
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncable::ModelTypeBitSet types_copy(pending_download_state_->added_types);
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (IsNigoriEnabled())
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      types_copy.set(syncable::NIGORI);
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    core_thread_.message_loop()->PostTask(FROM_HERE,
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         NewRunnableMethod(core_.get(),
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           &SyncBackendHost::Core::DoRequestConfig,
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           types_copy));
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pending_config_mode_state_.reset();
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Notify the SyncManager about the new types.
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  core_thread_.message_loop()->PostTask(FROM_HERE,
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableMethod(core_.get(),
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        &SyncBackendHost::Core::DoUpdateEnabledTypes));
472dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
473dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
474dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::EncryptDataTypes(
475dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const syncable::ModelTypeSet& encrypted_types) {
476dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  core_thread_.message_loop()->PostTask(FROM_HERE,
477dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen     NewRunnableMethod(core_.get(),
478dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                       &SyncBackendHost::Core::DoEncryptDataTypes,
479dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                       encrypted_types));
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::RequestNudge(const tracked_objects::Location& location) {
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  core_thread_.message_loop()->PostTask(FROM_HERE,
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoRequestNudge,
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        location));
486dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
487dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::ActivateDataType(
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DataTypeController* data_type_controller,
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChangeProcessor* change_processor) {
49172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(registrar_lock_);
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ensure that the given data type is in the PASSIVE group.
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_sync::ModelSafeRoutingInfo::iterator i =
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      registrar_.routing_info.find(data_type_controller->type());
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(i != registrar_.routing_info.end());
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK((*i).second == GROUP_PASSIVE);
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::ModelType type = data_type_controller->type();
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Change the data type's routing info to its group.
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.routing_info[type] = data_type_controller->model_safe_group();
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the data type's change processor to the list of change
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // processors so it can receive updates.
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(processors_.count(type), 0U);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  processors_[type] = change_processor;
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::DeactivateDataType(
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DataTypeController* data_type_controller,
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChangeProcessor* change_processor) {
51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(registrar_lock_);
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.routing_info.erase(data_type_controller->type());
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<syncable::ModelType, ChangeProcessor*>::size_type erased =
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      processors_.erase(data_type_controller->type());
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(erased, 1U);
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool SyncBackendHost::RequestClearServerData() {
5203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  core_thread_.message_loop()->PostTask(FROM_HERE,
5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     NewRunnableMethod(core_.get(),
5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     &SyncBackendHost::Core::DoRequestClearServerData));
5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return true;
5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickSyncBackendHost::Core::~Core() {
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid SyncBackendHost::Core::NotifyPassphraseRequired(bool for_decryption) {
53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!host_ || !host_->frontend_)
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
535dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (processing_passphrase_) {
536dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    VLOG(1) << "Core received OnPassphraseRequired while processing a "
537dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            << "passphrase. Silently dropping.";
538dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
539dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  host_->frontend_->OnPassphraseRequired(for_decryption);
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
543dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::Core::NotifyPassphraseFailed() {
544dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!host_ || !host_->frontend_)
545dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
546dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
547dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
548dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
549dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // When a passphrase fails, we just unset our waiting flag and trigger a
550dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // OnPassphraseRequired(true).
551dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processing_passphrase_ = false;
552dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  host_->frontend_->OnPassphraseRequired(true);
553dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
554dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::NotifyPassphraseAccepted(
5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& bootstrap_token) {
55772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!host_ || !host_->frontend_)
5584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return;
55972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
562dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processing_passphrase_ = false;
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  host_->PersistEncryptionBootstrapToken(bootstrap_token);
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  host_->frontend_->OnPassphraseAccepted();
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::NotifyUpdatedToken(const std::string& token) {
5684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!host_)
5694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return;
570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TokenAvailableDetails details(GaiaConstants::kSyncService, token);
5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NotificationService::current()->Notify(
5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationType::TOKEN_UPDATED,
5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NotificationService::AllSources(),
5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Details<const TokenAvailableDetails>(&details));
5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
578dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::Core::NotifyEncryptionComplete(
579dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const syncable::ModelTypeSet& encrypted_types) {
580dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!host_)
581dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
582dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
583dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  host_->frontend_->OnEncryptionComplete(encrypted_types);
584dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
585dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::FinishConfigureDataTypes() {
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop));
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop() {
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  host_->FinishConfigureDataTypesOnFrontendLoop();
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::CreateSyncNotifier(
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<net::URLRequestContextGetter>& request_context_getter) {
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string& client_info = webkit_glue::GetUserAgent(GURL());
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SyncNotifierFactory sync_notifier_factory(client_info);
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sync_notifier_.reset(sync_notifier_factory.CreateSyncNotifier(
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      *CommandLine::ForCurrentProcess(),
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      request_context_getter));
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSyncBackendHost::Core::DoInitializeOptions::DoInitializeOptions(
60672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const GURL& service_url,
60772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::HttpPostProviderFactory* http_bridge_factory,
60872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const sync_api::SyncCredentials& credentials,
60972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool delete_sync_data_folder,
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& restored_key_for_bootstrapping,
61172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool setup_for_test_mode)
61272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : service_url(service_url),
61372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      http_bridge_factory(http_bridge_factory),
61472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      credentials(credentials),
61572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      delete_sync_data_folder(delete_sync_data_folder),
61672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      restored_key_for_bootstrapping(restored_key_for_bootstrapping),
61772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      setup_for_test_mode(setup_for_test_mode) {
61872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
61972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSyncBackendHost::Core::DoInitializeOptions::~DoInitializeOptions() {}
62172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensync_api::UserShare* SyncBackendHost::GetUserShare() const {
6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(syncapi_initialized_);
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return core_->syncapi()->GetUserShare();
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::Status SyncBackendHost::GetDetailedStatus() {
6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(syncapi_initialized_);
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return core_->syncapi()->GetDetailedStatus();
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::StatusSummary SyncBackendHost::GetStatusSummary() {
6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(syncapi_initialized_);
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return core_->syncapi()->GetStatusSummary();
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 SyncBackendHost::GetAuthenticatedUsername() const {
6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(syncapi_initialized_);
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return UTF8ToUTF16(core_->syncapi()->GetAuthenticatedUsername());
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GoogleServiceAuthError& SyncBackendHost::GetAuthError() const {
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return last_auth_error_;
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SyncSessionSnapshot* SyncBackendHost::GetLastSessionSnapshot() const {
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return last_snapshot_.get();
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::GetWorkers(std::vector<ModelSafeWorker*>* out) {
65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(registrar_lock_);
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  out->clear();
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (WorkerMap::const_iterator it = registrar_.workers.begin();
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != registrar_.workers.end(); ++it) {
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    out->push_back((*it).second);
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) {
66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(registrar_lock_);
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ModelSafeRoutingInfo copy(registrar_.routing_info);
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  out->swap(copy);
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool SyncBackendHost::HasUnsyncedItems() const {
6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(syncapi_initialized_);
6673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return core_->syncapi()->HasUnsyncedItems();
6683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
6693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::Core::Core(SyncBackendHost* backend)
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : host_(backend),
67272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      syncapi_(new sync_api::SyncManager()),
67372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      sync_manager_observer_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      parent_router_(NULL),
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      processing_passphrase_(false),
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      deferred_nudge_for_cleanup_requested_(false) {
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper to construct a user agent string (ASCII) suitable for use by
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the syncapi for any HTTP communication. This string is used by the sync
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// backend for classifying client types when calculating statistics.
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string MakeUserAgentForSyncapi() {
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string user_agent;
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  user_agent = "Chrome ";
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  user_agent += "WIN ";
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_LINUX)
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  user_agent += "LINUX ";
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_FREEBSD)
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  user_agent += "FREEBSD ";
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_OPENBSD)
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  user_agent += "OPENBSD ";
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  user_agent += "MAC ";
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  chrome::VersionInfo version_info;
6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!version_info.is_valid()) {
6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DLOG(ERROR) << "Unable to create chrome::VersionInfo object";
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return user_agent;
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  user_agent += version_info.Version();
7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  user_agent += " (" + version_info.LastChange() + ")";
7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!version_info.IsOfficialBuild())
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    user_agent += "-devel";
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return user_agent;
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) {
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
711dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processing_passphrase_ = false;
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Blow away the partial or corrupt sync data folder before doing any more
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // initialization, if necessary.
7153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (options.delete_sync_data_folder) {
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DeleteSyncDataFolder();
7173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure that the directory exists before initializing the backend.
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If it already exists, this will do no harm.
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success = file_util::CreateDirectory(host_->sync_data_folder_path());
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(success);
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncapi_->AddObserver(this);
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath& path_str = host_->sync_data_folder_path();
7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  success = syncapi_->Init(
7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      path_str,
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (options.service_url.host() + options.service_url.path()).c_str(),
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      options.service_url.EffectiveIntPort(),
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      options.service_url.SchemeIsSecure(),
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      options.http_bridge_factory,
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      host_,  // ModelSafeWorkerRegistrar.
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MakeUserAgentForSyncapi().c_str(),
7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      options.credentials,
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      sync_notifier_.get(),
7363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      options.restored_key_for_bootstrapping,
7373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      options.setup_for_test_mode);
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(success) << "Syncapi initialization failed!";
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::DoUpdateCredentials(
7423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const SyncCredentials& credentials) {
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
7443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  syncapi_->UpdateCredentials(credentials);
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::DoUpdateEnabledTypes() {
748dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncapi_->UpdateEnabledTypes();
750dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
751dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::DoStartSyncing() {
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncapi_->StartSyncing();
755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (deferred_nudge_for_cleanup_requested_)
756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    syncapi_->RequestNudge(FROM_HERE);
757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  deferred_nudge_for_cleanup_requested_ = false;
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid SyncBackendHost::Core::DoSetPassphrase(const std::string& passphrase,
7614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                            bool is_explicit) {
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
7634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  syncapi_->SetPassphrase(passphrase, is_explicit);
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
766dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool SyncBackendHost::Core::processing_passphrase() const {
767dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(MessageLoop::current() == host_->frontend_loop_);
768dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return processing_passphrase_;
769dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
770dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
771dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::Core::set_processing_passphrase() {
772dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(MessageLoop::current() == host_->frontend_loop_);
773dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  processing_passphrase_ = true;
774dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
775dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
776dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::Core::DoEncryptDataTypes(
777dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const syncable::ModelTypeSet& encrypted_types) {
778dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
779dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  syncapi_->EncryptDataTypes(encrypted_types);
780dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
781dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::DoRequestConfig(
783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const syncable::ModelTypeBitSet& added_types) {
784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncapi_->RequestConfig(added_types);
785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::DoStartConfiguration(Callback0::Type* callback) {
788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncapi_->StartConfigurationMode(callback);
789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochUIModelWorker* SyncBackendHost::ui_worker() {
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ModelSafeWorker* w = registrar_.workers[GROUP_UI];
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (w == NULL)
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (w->GetModelSafeGroup() != GROUP_UI)
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return static_cast<UIModelWorker*>(w);
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::DoShutdown(bool sync_disabled) {
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  save_changes_timer_.Stop();
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncapi_->Shutdown();  // Stops the SyncerThread.
80572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncapi_->RemoveObserver(this);
80672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DisconnectChildJsEventRouter();
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->ui_worker()->OnSyncerShutdownComplete();
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (sync_disabled)
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DeleteSyncDataFolder();
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_ = NULL;
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8153345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickChangeProcessor* SyncBackendHost::Core::GetProcessor(
8163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    syncable::ModelType model_type) {
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<syncable::ModelType, ChangeProcessor*>::const_iterator it =
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      host_->processors_.find(model_type);
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Until model association happens for a datatype, it will not appear in
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the processors list.  During this time, it is OK to drop changes on
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the floor (since model association has not happened yet).  When the
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // data type is activated, model association takes place then the change
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // processor is added to the processors_ list.  This all happens on
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the UI thread so we will never drop any changes after model
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // association.
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (it == host_->processors_.end())
8283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return NULL;
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!IsCurrentThreadSafeForModel(model_type)) {
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "Changes applied on wrong thread.";
8323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return NULL;
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now that we're sure we're on the correct thread, we can access the
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ChangeProcessor.
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChangeProcessor* processor = it->second;
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ensure the change processor is willing to accept changes.
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!processor->IsRunning())
8413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return NULL;
8423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return processor;
8443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
8453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::OnChangesApplied(
8473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    syncable::ModelType model_type,
8483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const sync_api::BaseTransaction* trans,
8493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const sync_api::SyncManager::ChangeRecord* changes,
8503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    int change_count) {
8513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!host_ || !host_->frontend_) {
8523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DCHECK(false) << "OnChangesApplied called after Shutdown?";
8533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
8543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
8553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ChangeProcessor* processor = GetProcessor(model_type);
8563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!processor)
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  processor->ApplyChangesFromSyncModel(trans, changes, change_count);
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::OnChangesComplete(
8633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    syncable::ModelType model_type) {
8643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!host_ || !host_->frontend_) {
8653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DCHECK(false) << "OnChangesComplete called after Shutdown?";
8663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
8673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
8683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ChangeProcessor* processor = GetProcessor(model_type);
8703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!processor)
8713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
8723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This call just notifies the processor that it can commit, it already
8743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // buffered any changes it plans to makes so needs no further information.
8753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  processor->CommitChangesFromSyncModel();
8763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
8773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::OnSyncCycleCompleted(
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const SyncSessionSnapshot* snapshot) {
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &Core::HandleSyncCycleCompletedOnFrontendLoop,
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new SyncSessionSnapshot(*snapshot)));
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::HandleSyncCycleCompletedOnFrontendLoop(
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SyncSessionSnapshot* snapshot) {
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host_ || !host_->frontend_)
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->last_snapshot_.reset(snapshot);
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const syncable::ModelTypeSet& to_migrate =
895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      snapshot->syncer_status.types_needing_local_migration;
896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!to_migrate.empty())
897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    host_->frontend_->OnMigrationNeededForTypes(to_migrate);
898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we are waiting for a configuration change, check here to see
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // if this sync cycle has initialized all of the types we've been
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // waiting for.
902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (host_->pending_download_state_.get()) {
903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool found_all_added = true;
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (syncable::ModelTypeSet::const_iterator it =
905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             host_->pending_download_state_->initial_types.begin();
906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         it != host_->pending_download_state_->initial_types.end();
907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         ++it) {
908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (host_->pending_download_state_->added_types.test(*it))
909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        found_all_added &= snapshot->initial_sync_ended.test(*it);
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!found_all_added) {
912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NOTREACHED() << "Update didn't return updates for all types requested.";
913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      host_->pending_download_state_->ready_task->Run();
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    host_->pending_download_state_.reset();
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_->OnSyncCycleCompleted();
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::OnInitializationComplete() {
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host_ || !host_->frontend_)
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;  // We may have been told to Shutdown before initialization
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             // completed.
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We could be on some random sync backend thread, so MessageLoop::current()
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // can definitely be null in here.
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_loop_->PostTask(FROM_HERE,
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this,
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        &Core::HandleInitalizationCompletedOnFrontendLoop));
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialization is complete, so we can schedule recurring SaveChanges.
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->core_thread_.message_loop()->PostTask(FROM_HERE,
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this, &Core::StartSavingChanges));
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::HandleInitalizationCompletedOnFrontendLoop() {
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host_)
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->HandleInitializationCompletedOnFrontendLoop();
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::HandleInitializationCompletedOnFrontendLoop() {
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!frontend_)
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
9463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  syncapi_initialized_ = true;
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  frontend_->OnBackendInitialized();
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SyncBackendHost::Core::IsCurrentThreadSafeForModel(
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    syncable::ModelType model_type) {
95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(host_->registrar_lock_);
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_sync::ModelSafeRoutingInfo::const_iterator routing_it =
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      host_->registrar_.routing_info.find(model_type);
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (routing_it == host_->registrar_.routing_info.end())
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_sync::ModelSafeGroup group = routing_it->second;
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WorkerMap::const_iterator worker_it = host_->registrar_.workers.find(group);
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (worker_it == host_->registrar_.workers.end())
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ModelSafeWorker* worker = worker_it->second;
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return worker->CurrentThreadIsWorkThread();
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) {
9673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Post to our core loop so we can modify state. Could be on another thread.
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_loop_->PostTask(FROM_HERE,
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this, &Core::HandleAuthErrorEventOnFrontendLoop,
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      auth_error));
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
973201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid SyncBackendHost::Core::OnPassphraseRequired(bool for_decryption) {
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_loop_->PostTask(FROM_HERE,
975201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      NewRunnableMethod(this, &Core::NotifyPassphraseRequired, for_decryption));
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
978dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::Core::OnPassphraseFailed() {
979dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  host_->frontend_loop_->PostTask(FROM_HERE,
980dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NewRunnableMethod(this, &Core::NotifyPassphraseFailed));
981dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
982dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
9833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::OnPassphraseAccepted(
9843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& bootstrap_token) {
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_loop_->PostTask(FROM_HERE,
9863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NewRunnableMethod(this, &Core::NotifyPassphraseAccepted,
9873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          bootstrap_token));
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::OnStopSyncingPermanently() {
991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &Core::HandleStopSyncingPermanentlyOnFrontendLoop));
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::OnUpdatedToken(const std::string& token) {
9963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
9973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &Core::NotifyUpdatedToken, token));
9983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::OnClearServerDataSucceeded() {
10013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
10023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &Core::HandleClearServerDataSucceededOnFrontendLoop));
10033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
10043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::OnClearServerDataFailed() {
10063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
10073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &Core::HandleClearServerDataFailedOnFrontendLoop));
10083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
10093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1010dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SyncBackendHost::Core::OnEncryptionComplete(
1011dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const syncable::ModelTypeSet& encrypted_types) {
1012dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  host_->frontend_loop_->PostTask(
1013dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      FROM_HERE,
1014dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NewRunnableMethod(this, &Core::NotifyEncryptionComplete,
1015dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        encrypted_types));
1016dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1017dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
101872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::RouteJsEvent(
101972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& name, const JsArgList& args,
102072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const JsEventHandler* target) {
102172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  host_->frontend_loop_->PostTask(
102272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      FROM_HERE, NewRunnableMethod(
102372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          this, &Core::RouteJsEventOnFrontendLoop, name, args, target));
102472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
102572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::HandleStopSyncingPermanentlyOnFrontendLoop() {
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host_ || !host_->frontend_)
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_->OnStopSyncingPermanently();
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::HandleClearServerDataSucceededOnFrontendLoop() {
10333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!host_ || !host_->frontend_)
10343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
10353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  host_->frontend_->OnClearServerDataSucceeded();
10363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
10373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::HandleClearServerDataFailedOnFrontendLoop() {
10393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!host_ || !host_->frontend_)
10403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
10413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  host_->frontend_->OnClearServerDataFailed();
10423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
10433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::HandleAuthErrorEventOnFrontendLoop(
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GoogleServiceAuthError& new_auth_error) {
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host_ || !host_->frontend_)
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->last_auth_error_ = new_auth_error;
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_->frontend_->OnAuthError();
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::RouteJsEventOnFrontendLoop(
105672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& name, const JsArgList& args,
105772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const JsEventHandler* target) {
105872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!host_ || !parent_router_)
105972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
106072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
106172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
106272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
106372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  parent_router_->RouteJsEvent(name, args, target);
106472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
106572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::StartSavingChanges() {
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  save_changes_timer_.Start(
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds),
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      this, &Core::SaveChanges);
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::DoRequestNudge(
1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const tracked_objects::Location& nudge_location) {
1074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  syncapi_->RequestNudge(nudge_location);
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SyncBackendHost::Core::DoRequestClearServerData() {
10783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  syncapi_->RequestClearServerData();
10793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
10803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::SaveChanges() {
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncapi_->SaveChanges();
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SyncBackendHost::Core::DeleteSyncDataFolder() {
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (file_util::DirectoryExists(host_->sync_data_folder_path())) {
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!file_util::Delete(host_->sync_data_folder_path(), true))
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      LOG(DFATAL) << "Could not delete the Sync Data folder.";
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::SetParentJsEventRouter(JsEventRouter* router) {
109372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
109472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(router);
109572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  parent_router_ = router;
109672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MessageLoop* core_message_loop = host_->core_thread_.message_loop();
109772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CHECK(core_message_loop);
109872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  core_message_loop->PostTask(
109972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      FROM_HERE,
110072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableMethod(this,
110172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        &SyncBackendHost::Core::ConnectChildJsEventRouter));
110272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
110372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
110472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::RemoveParentJsEventRouter() {
110572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
110672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  parent_router_ = NULL;
110772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MessageLoop* core_message_loop = host_->core_thread_.message_loop();
110872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CHECK(core_message_loop);
110972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  core_message_loop->PostTask(
111072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      FROM_HERE,
111172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableMethod(this,
111272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        &SyncBackendHost::Core::DisconnectChildJsEventRouter));
111372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
111472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
111572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst JsEventRouter* SyncBackendHost::Core::GetParentJsEventRouter() const {
111672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
111772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return parent_router_;
111872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
111972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
112072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::ProcessMessage(
112172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& name, const JsArgList& args,
112272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const JsEventHandler* sender) {
112372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_);
112472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MessageLoop* core_message_loop = host_->core_thread_.message_loop();
112572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CHECK(core_message_loop);
112672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  core_message_loop->PostTask(
112772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      FROM_HERE,
112872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableMethod(this,
112972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        &SyncBackendHost::Core::DoProcessMessage,
113072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        name, args, sender));
113172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
113272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
113372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::ConnectChildJsEventRouter() {
113472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->core_thread_.message_loop());
113572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We need this check since AddObserver() can be called at most once
113672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // for a given observer.
113772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!syncapi_->GetJsBackend()->GetParentJsEventRouter()) {
113872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncapi_->GetJsBackend()->SetParentJsEventRouter(this);
113972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncapi_->AddObserver(&sync_manager_observer_);
114072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
114172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
114272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
114372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::DisconnectChildJsEventRouter() {
114472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->core_thread_.message_loop());
114572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncapi_->GetJsBackend()->RemoveParentJsEventRouter();
114672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncapi_->RemoveObserver(&sync_manager_observer_);
114772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
114872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
114972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SyncBackendHost::Core::DoProcessMessage(
115072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& name, const JsArgList& args,
115172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const JsEventHandler* sender) {
115272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->core_thread_.message_loop());
115372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncapi_->GetJsBackend()->ProcessMessage(name, args, sender);
115472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
115572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SyncBackendHost::Core::DeferNudgeForCleanup() {
1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK_EQ(MessageLoop::current(), host_->core_thread_.message_loop());
1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  deferred_nudge_for_cleanup_requested_ = true;
1159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser_sync
1162