172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian 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 "chrome/browser/sync/profile_sync_service.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <stddef.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <ostream>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <utility>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/basictypes.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/compiler_specific.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/message_loop.h"
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/stringprintf.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/threading/thread_restrictions.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/net/gaia/token_service.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/backend_migrator.h"
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/engine/syncapi.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/change_processor.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/data_type_controller.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/data_type_manager.h"
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/sync/glue/session_data_type_controller.h"
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/js_arg_list.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_factory.h"
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/sync/signin_manager.h"
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser.h"
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/gaia_constants.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/time_format.h"
43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/url_constants.h"
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_details.h"
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/gfx/native_widget_types.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::ChangeProcessor;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::DataTypeController;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::DataTypeManager;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::SyncBackendHost;
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing sync_api::SyncCredentials;
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef GoogleServiceAuthError AuthError;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* ProfileSyncService::kSyncServerUrl =
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "https://clients4.google.com/chrome-sync";
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* ProfileSyncService::kDevServerUrl =
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "https://clients4.google.com/chrome-sync/dev";
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kSyncClearDataTimeoutInSeconds = 60;  // 1 minute.
66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory,
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       Profile* profile,
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                       const std::string& cros_user)
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : last_auth_error_(AuthError::None()),
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      observed_passphrase_required_(false),
72201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      passphrase_required_for_decryption_(false),
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      passphrase_migration_in_progress_(false),
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      factory_(factory),
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_(profile),
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      cros_user_(cros_user),
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_service_url_(kDevServerUrl),
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      backend_initialized_(false),
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_auth_in_progress_(false),
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      wizard_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      unrecoverable_error_detected_(false),
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      scoped_runnable_method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      expect_sync_configuration_aborted_(false),
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      clear_server_data_state_(CLEAR_NOT_STARTED) {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 NotificationType::SYNC_DATA_TYPES_UPDATED,
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 Source<Profile>(profile));
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // By default, dev & chromium users will go to the development servers.
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Dev servers have more features than standard sync servers.
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Chrome stable and beta builds will go to the standard sync servers.
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GOOGLE_CHROME_BUILD)
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // GetVersionStringModifier hits the registry. See http://crbug.com/70380.
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For stable, this is "". For dev, this is "dev". For beta, this is "beta".
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For daily, this is "canary build".
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // For Linux Chromium builds, this could be anything depending on the
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // distribution, so always direct those users to dev server urls.
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If this is an official build, it will always be one of the above.
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string channel = platform_util::GetVersionStringModifier();
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (channel.empty() || channel == "beta") {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_service_url_ = GURL(kSyncServerUrl);
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  tried_implicit_gaia_remove_when_bug_62103_fixed_ = false;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProfileSyncService::~ProfileSyncService() {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Shutdown(false);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ProfileSyncService::AreCredentialsAvailable() {
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (IsManaged()) {
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // CrOS user is always logged in. Chrome uses signin_ to check logged in.
119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!cros_user_.empty() || !signin_->GetUsername().empty()) {
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // TODO(chron): Verify CrOS unit test behavior.
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (profile()->GetTokenService() &&
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        profile()->GetTokenService()->HasTokenForService(
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            GaiaConstants::kSyncService)) {
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return true;
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return false;
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::Initialize() {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitSettings();
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RegisterPreferences();
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Watch the preference that indicates sync is managed so we can take
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // appropriate action.
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_sync_managed_.Init(prefs::kSyncManaged, profile_->GetPrefs(), this);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For now, the only thing we can do through policy is to turn sync off.
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (IsManaged()) {
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DisableForUser();
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  RegisterAuthNotifications();
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // In Chrome, we integrate a SigninManager which works with the sync
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // setup wizard to kick off the TokenService. CrOS does its own plumbing
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // for the TokenService.
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (cros_user_.empty()) {
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Will load tokens from DB and broadcast Token events after.
151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Note: We rely on signin_ != NULL unless !cros_user_.empty().
152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_.reset(new SigninManager());
153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_->Initialize(profile_);
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!HasSyncSetupCompleted()) {
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DisableForUser();  // Clean up in case of previous crash / setup abort.
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Under ChromeOS, just autostart it anyway if creds are here and start
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // is not being suppressed by preferences.
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!cros_user_.empty() &&
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        !profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart) &&
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        AreCredentialsAvailable()) {
164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      StartUp();
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else if (AreCredentialsAvailable()) {
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // If we have credentials and sync setup finished, autostart the backend.
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Note that if we haven't finished setting up sync, backend bring up will
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // be done by the wizard.
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    StartUp();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::RegisterAuthNotifications() {
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this,
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 NotificationType::TOKEN_AVAILABLE,
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 Source<TokenService>(profile_->GetTokenService()));
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this,
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 NotificationType::TOKEN_LOADING_FINISHED,
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 Source<TokenService>(profile_->GetTokenService()));
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this,
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL,
183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                 Source<Profile>(profile_));
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this,
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 NotificationType::GOOGLE_SIGNIN_FAILED,
186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                 Source<Profile>(profile_));
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::RegisterDataTypeController(
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DataTypeController* data_type_controller) {
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data_type_controllers_[data_type_controller->type()] =
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      data_type_controller;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbrowser_sync::SessionModelAssociator*
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ProfileSyncService::GetSessionModelAssociator() {
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (data_type_controllers_.find(syncable::SESSIONS) ==
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      data_type_controllers_.end() ||
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      data_type_controllers_.find(syncable::SESSIONS)->second->state() !=
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DataTypeController::RUNNING) {
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return NULL;
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return static_cast<browser_sync::SessionDataTypeController*>(
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      data_type_controllers_.find(
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      syncable::SESSIONS)->second.get())->GetModelAssociator();
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::ResetClearServerDataState() {
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  clear_server_data_state_ = CLEAR_NOT_STARTED;
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProfileSyncService::ClearServerDataState
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ProfileSyncService::GetClearServerDataState() {
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return clear_server_data_state_;
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::GetDataTypeControllerStates(
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_sync::DataTypeController::StateMap* state_map) const {
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    for (browser_sync::DataTypeController::TypeMap::const_iterator iter =
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick         data_type_controllers_.begin(); iter != data_type_controllers_.end();
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick         ++iter)
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (*state_map)[iter->first] = iter->second.get()->state();
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::InitSettings() {
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Override the sync server URL from the command-line, if sync server
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // command-line argument exists.
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (command_line.HasSwitch(switches::kSyncServiceURL)) {
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string value(command_line.GetSwitchValueASCII(
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        switches::kSyncServiceURL));
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!value.empty()) {
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL custom_sync_url(value);
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (custom_sync_url.is_valid()) {
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        sync_service_url_ = custom_sync_url;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        LOG(WARNING) << "The following sync URL specified at the command-line "
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     << "is invalid: " << value;
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::RegisterPreferences() {
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* pref_service = profile_->GetPrefs();
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pref_service->FindPreference(prefs::kSyncLastSyncedTime))
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0);
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncHasSetupCompleted, false);
2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pref_service->RegisterBooleanPref(prefs::kSyncSuppressStart, false);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If you've never synced before, or if you're using Chrome OS, all datatypes
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are on by default.
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(nick): Perhaps a better model would be to always default to false,
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and explicitly call SetDataTypes() when the user shows the wizard.
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool enable_by_default = true;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool enable_by_default =
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !pref_service->HasPrefPath(prefs::kSyncHasSetupCompleted);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncBookmarks, true);
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pref_service->RegisterBooleanPref(prefs::kSyncPasswords, enable_by_default);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncPreferences, enable_by_default);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncAutofill, enable_by_default);
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncThemes, enable_by_default);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncTypedUrls, enable_by_default);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncExtensions, enable_by_default);
2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pref_service->RegisterBooleanPref(prefs::kSyncApps, enable_by_default);
2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pref_service->RegisterBooleanPref(prefs::kSyncSessions, enable_by_default);
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kKeepEverythingSynced,
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      enable_by_default);
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->RegisterBooleanPref(prefs::kSyncManaged, false);
2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pref_service->RegisterStringPref(prefs::kEncryptionBootstrapToken, "");
27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
27921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  pref_service->RegisterBooleanPref(prefs::kSyncAutofillProfile,
28021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      enable_by_default);
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::ClearPreferences() {
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* pref_service = profile_->GetPrefs();
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->ClearPref(prefs::kSyncLastSyncedTime);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->ClearPref(prefs::kSyncHasSetupCompleted);
2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pref_service->ClearPref(prefs::kEncryptionBootstrapToken);
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(nick): The current behavior does not clear e.g. prefs::kSyncBookmarks.
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Is that really what we want?
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pref_service->ScheduleSavePersistentPrefs();
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickSyncCredentials ProfileSyncService::GetCredentials() {
2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SyncCredentials credentials;
296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  credentials.email = !cros_user_.empty() ? cros_user_ : signin_->GetUsername();
2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(!credentials.email.empty());
2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TokenService* service = profile_->GetTokenService();
2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  credentials.sync_token = service->GetTokenForService(
3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GaiaConstants::kSyncService);
3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return credentials;
3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::InitializeBackend(bool delete_sync_data_folder) {
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!backend_.get()) {
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::ModelTypeSet types;
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If sync setup hasn't finished, we don't want to initialize routing info
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for any data types so that we don't download updates for types that the
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // user chooses not to sync on the first DownloadUpdatesCommand.
3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (HasSyncSetupCompleted()) {
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetPreferredDataTypes(&types);
3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SyncCredentials credentials = GetCredentials();
3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  backend_->Initialize(this,
32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       sync_service_url_,
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       types,
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       profile_->GetRequestContext(),
3243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       credentials,
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       delete_sync_data_folder);
3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::CreateBackend() {
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  backend_.reset(new SyncBackendHost(profile_));
33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ProfileSyncService::IsEncryptedDatatypeEnabled() const {
333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return !encrypted_types_.empty();
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::StartUp() {
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't start up multiple times.
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (backend_.get()) {
339513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    VLOG(1) << "Skipping bringing up backend host.";
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(AreCredentialsAvailable());
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_synced_time_ = base::Time::FromInternalValue(
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_->GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime));
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreateBackend();
3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize the backend.  Every time we start up a new SyncBackendHost,
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we'll want to start from a fresh SyncDB, so delete any old one that might
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be there.
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeBackend(!HasSyncSetupCompleted());
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::Shutdown(bool sync_disabled) {
3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Stop all data type controllers, if needed.
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (data_type_manager_.get()) {
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (data_type_manager_->state() != DataTypeManager::STOPPED) {
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      data_type_manager_->Stop();
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    registrar_.Remove(this,
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                      NotificationType::SYNC_CONFIGURE_START,
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                      Source<DataTypeManager>(data_type_manager_.get()));
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    registrar_.Remove(this,
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                      NotificationType::SYNC_CONFIGURE_DONE,
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                      Source<DataTypeManager>(data_type_manager_.get()));
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    data_type_manager_.reset();
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  js_event_handlers_.RemoveBackend();
37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Move aside the backend so nobody else tries to use it while we are
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // shutting it down.
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<SyncBackendHost> doomed_backend(backend_.release());
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (doomed_backend.get()) {
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    doomed_backend->Shutdown(sync_disabled);
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    doomed_backend.reset();
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clear various flags.
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_auth_in_progress_ = false;
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  backend_initialized_ = false;
386731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  observed_passphrase_required_ = false;
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_attempted_user_email_.clear();
388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  last_auth_error_ = GoogleServiceAuthError::None();
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::ClearServerData() {
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  clear_server_data_state_ = CLEAR_CLEARING;
393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  clear_server_data_timer_.Start(
394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      base::TimeDelta::FromSeconds(kSyncClearDataTimeoutInSeconds), this,
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      &ProfileSyncService::OnClearServerDataTimeout);
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  backend_->RequestClearServerData();
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::DisableForUser() {
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Clear prefs (including SyncSetupHasCompleted) before shutting down so
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // PSS clients don't think we're set up while we're shutting down.
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClearPreferences();
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Shutdown(true);
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (signin_.get()) {
406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_->SignOut();
4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
40972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProfileSyncService::HasSyncSetupCompleted() const {
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted);
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::SetSyncSetupCompleted() {
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* prefs = profile()->GetPrefs();
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->SetBoolean(prefs::kSyncHasSetupCompleted, true);
4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  prefs->SetBoolean(prefs::kSyncSuppressStart, false);
4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->ScheduleSavePersistentPrefs();
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::UpdateLastSyncedTime() {
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_synced_time_ = base::Time::Now();
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->SetInt64(prefs::kSyncLastSyncedTime,
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      last_synced_time_.ToInternalValue());
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->ScheduleSavePersistentPrefs();
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::NotifyObservers() {
43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // TODO(akalin): Make an Observer subclass that listens and does the
43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // event routing.
43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  js_event_handlers_.RouteJsEvent(
43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "onSyncServiceStateChanged", browser_sync::JsArgList(), NULL);
43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char* ProfileSyncService::GetPrefNameForDataType(
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    syncable::ModelType data_type) {
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (data_type) {
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::BOOKMARKS:
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncBookmarks;
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::PASSWORDS:
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncPasswords;
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::PREFERENCES:
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncPreferences;
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::AUTOFILL:
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncAutofill;
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case syncable::AUTOFILL_PROFILE:
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return prefs::kSyncAutofillProfile;
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::THEMES:
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncThemes;
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::TYPED_URLS:
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncTypedUrls;
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case syncable::EXTENSIONS:
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return prefs::kSyncExtensions;
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case syncable::APPS:
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return prefs::kSyncApps;
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case syncable::SESSIONS:
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return prefs::kSyncSessions;
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
46672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NOTREACHED();
46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return NULL;
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// An invariant has been violated.  Transition to an error state where we try
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to do as little work as possible, to avoid further corruption or crashes.
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnUnrecoverableError(
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const tracked_objects::Location& from_here,
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& message) {
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unrecoverable_error_detected_ = true;
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unrecoverable_error_message_ = message;
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unrecoverable_error_location_.reset(
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new tracked_objects::Location(from_here.function_name(),
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    from_here.file_name(),
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    from_here.line_number()));
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the wizard so it can inform the user only if it is already open.
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  wizard_.Step(SyncSetupWizard::FATAL_ERROR);
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  LOG(ERROR) << "Unrecoverable error detected -- ProfileSyncService unusable."
4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      << message;
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string location;
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  from_here.Write(true, true, &location);
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LOG(ERROR) << location;
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Shut all data types down.
4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop::current()->PostTask(FROM_HERE,
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        scoped_runnable_method_factory_.NewRunnableMethod(
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &ProfileSyncService::Shutdown, true));
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnBackendInitialized() {
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  backend_initialized_ = true;
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  js_event_handlers_.SetBackend(backend_->GetJsBackend());
50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The very first time the backend initializes is effectively the first time
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we can say we successfully "synced".  last_synced_time_ will only be null
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in this case, because the pref wasn't restored on StartUp.
5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (last_synced_time_.is_null()) {
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateLastSyncedTime();
5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!cros_user_.empty()) {
5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)) {
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ShowConfigure(NULL, true);
5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    } else {
5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      SetSyncSetupCompleted();
5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (HasSyncSetupCompleted()) {
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConfigureDataTypeManager();
5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnSyncCycleCompleted() {
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateLastSyncedTime();
526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(2) << "Notifying observers sync cycle completed";
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::UpdateAuthErrorState(
5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const GoogleServiceAuthError& error) {
5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  last_auth_error_ = error;
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Protect against the in-your-face dialogs that pop out of nowhere.
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Require the user to click somewhere to run the setup wizard in the case
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of a steady-state auth failure.
5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (WizardIsVisible()) {
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wizard_.Step(AuthError::NONE == last_auth_error_.state() ?
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SyncSetupWizard::GAIA_SUCCESS : SyncSetupWizard::GAIA_LOGIN);
5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    auth_error_time_ = base::TimeTicks::Now();
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!auth_start_time_.is_null()) {
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UMA_HISTOGRAM_TIMES("Sync.AuthorizationTimeInNetwork",
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    base::TimeTicks::Now() - auth_start_time_);
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    auth_start_time_ = base::TimeTicks();
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_auth_in_progress_ = false;
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Fan the notification out to interested UI-thread components.
55172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::OnAuthError() {
5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateAuthErrorState(backend_->GetAuthError());
5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnStopSyncingPermanently() {
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (SetupInProgress()) {
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    expect_sync_configuration_aborted_ = true;
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile_->GetPrefs()->SetBoolean(prefs::kSyncSuppressStart, true);
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DisableForUser();
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid ProfileSyncService::OnClearServerDataTimeout() {
568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (clear_server_data_state_ != CLEAR_SUCCEEDED &&
569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      clear_server_data_state_ != CLEAR_FAILED) {
570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    clear_server_data_state_ = CLEAR_FAILED;
57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NotifyObservers();
572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
574731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::OnClearServerDataFailed() {
576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  clear_server_data_timer_.Stop();
577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
578731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Only once clear has succeeded there is no longer a need to transition to
579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // a failed state as sync is disabled locally.  Also, no need to fire off
580731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // the observers if the state didn't change (i.e. it was FAILED before).
581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (clear_server_data_state_ != CLEAR_SUCCEEDED &&
582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      clear_server_data_state_ != CLEAR_FAILED) {
583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    clear_server_data_state_ = CLEAR_FAILED;
58472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NotifyObservers();
585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ProfileSyncService::OnClearServerDataSucceeded() {
589731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  clear_server_data_timer_.Stop();
590731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
591731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Even if the timout fired, we still transition to the succeeded state as
592731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // we want UI to update itself and no longer allow the user to press "clear"
593731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (clear_server_data_state_ != CLEAR_SUCCEEDED) {
594731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    clear_server_data_state_ = CLEAR_SUCCEEDED;
59572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NotifyObservers();
596731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
59972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::OnPassphraseRequired(bool for_decryption) {
60072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(backend_.get());
60172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(backend_->IsNigoriEnabled());
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(lipalani) : add this check to other locations as well.
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (unrecoverable_error_detected_) {
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // When unrecoverable error is detected we post a task to shutdown the
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // backend. The task might not have executed yet.
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
60972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  observed_passphrase_required_ = true;
61072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  passphrase_required_for_decryption_ = for_decryption;
61172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // First try supplying gaia password as the passphrase.
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!gaia_password_.empty()) {
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetPassphrase(gaia_password_, false, true);
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    gaia_password_ = std::string();
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If the above failed then try the custom passphrase the user might have
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // entered in setup.
62172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!cached_passphrase_.value.empty()) {
62272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SetPassphrase(cached_passphrase_.value,
62372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  cached_passphrase_.is_explicit,
62472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  cached_passphrase_.is_creation);
62572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    cached_passphrase_ = CachedPassphrase();
62672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
62772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
62872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We will skip the passphrase prompt and suppress the warning
63072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // if the passphrase is needed for decryption but the user is
63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // not syncing an encrypted data type on this machine.
63272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Otherwise we prompt.
63372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!IsEncryptedDatatypeEnabled() && for_decryption) {
63472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    OnPassphraseAccepted();
63572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
63672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
63772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
638dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (WizardIsVisible() && for_decryption) {
63972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE);
64072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
64172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
64272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
64372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
64472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
64572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::OnPassphraseAccepted() {
64672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Make sure the data types that depend on the passphrase are started at
64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // this time.
64872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::ModelTypeSet types;
64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GetPreferredDataTypes(&types);
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Reset "passphrase_required" flag before configuring the DataTypeManager
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // since we know we no longer require the passphrase.
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  observed_passphrase_required_ = false;
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (data_type_manager_.get())
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    data_type_manager_->Configure(types);
65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
65772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
65872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  wizard_.Step(SyncSetupWizard::DONE);
65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
661dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProfileSyncService::OnEncryptionComplete(
662dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const syncable::ModelTypeSet& encrypted_types) {
663dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (encrypted_types_ != encrypted_types) {
664dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    encrypted_types_ = encrypted_types;
665dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    NotifyObservers();
666dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
667dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
668dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileSyncService::OnMigrationNeededForTypes(
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const syncable::ModelTypeSet& types) {
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(backend_initialized_);
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(data_type_manager_.get());
673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Migrator must be valid, because we don't sync until it is created and this
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // callback originates from a sync cycle.
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  migrator_->MigrateTypes(types);
677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
6783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileSyncService::ShowLoginDialog(gfx::NativeWindow parent_window) {
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (WizardIsVisible()) {
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wizard_.Focus();
682dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Force the wizard to step to the login screen (which will only actually
683dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // happen if the transition is valid).
684dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    wizard_.Step(SyncSetupWizard::GAIA_LOGIN);
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!auth_error_time_.is_null()) {
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UMA_HISTOGRAM_LONG_TIMES("Sync.ReauthorizationTime",
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             base::TimeTicks::Now() - auth_error_time_);
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    auth_error_time_ = base::TimeTicks();  // Reset auth_error_time_ to null.
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  wizard_.Step(SyncSetupWizard::GAIA_LOGIN);
6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
69672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
69772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
69872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
69972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::ShowErrorUI(gfx::NativeWindow parent_window) {
70072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (observed_passphrase_required()) {
70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (IsUsingSecondaryPassphrase())
70272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      PromptForExistingPassphrase(parent_window);
70372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    else
70472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SigninForPassphraseMigration(parent_window);
70572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
70672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
70772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const GoogleServiceAuthError& error = GetAuthError();
70872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS ||
70972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error.state() == GoogleServiceAuthError::CAPTCHA_REQUIRED ||
71072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error.state() == GoogleServiceAuthError::ACCOUNT_DELETED ||
71172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error.state() == GoogleServiceAuthError::ACCOUNT_DISABLED ||
71272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE) {
71372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ShowLoginDialog(parent_window);
71472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileSyncService::ShowConfigure(
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    gfx::NativeWindow parent_window, bool sync_everything) {
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (WizardIsVisible()) {
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wizard_.Focus();
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (sync_everything)
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    wizard_.Step(SyncSetupWizard::SYNC_EVERYTHING);
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    wizard_.Step(SyncSetupWizard::CONFIGURE);
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid ProfileSyncService::PromptForExistingPassphrase(
7323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    gfx::NativeWindow parent_window) {
7333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (WizardIsVisible()) {
7343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    wizard_.Focus();
7353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return;
7363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
7383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE);
7393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
7403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::SigninForPassphraseMigration(
7423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    gfx::NativeWindow parent_window) {
74372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  passphrase_migration_in_progress_ = true;
74472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ShowLoginDialog(parent_window);
7453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
7463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::StatusSummary ProfileSyncService::QuerySyncStatusSummary() {
7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (backend_.get() && backend_initialized_)
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return backend_->GetStatusSummary();
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return SyncBackendHost::Status::OFFLINE_UNUSABLE;
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSyncBackendHost::Status ProfileSyncService::QueryDetailedSyncStatus() {
7553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (backend_.get() && backend_initialized_) {
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return backend_->GetDetailedStatus();
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SyncBackendHost::Status status =
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        { SyncBackendHost::Status::OFFLINE_UNUSABLE };
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return status;
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ProfileSyncService::SetupInProgress() const {
7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return !HasSyncSetupCompleted() && WizardIsVisible();
7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string ProfileSyncService::BuildSyncStatusSummaryText(
76972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const sync_api::SyncManager::Status::Summary& summary) {
77072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const char* strings[] = {"INVALID", "OFFLINE", "OFFLINE_UNSYNCED", "SYNCING",
77172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "READY", "CONFLICT", "OFFLINE_UNUSABLE"};
77272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  COMPILE_ASSERT(arraysize(strings) ==
77372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 sync_api::SyncManager::Status::SUMMARY_STATUS_COUNT,
77472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 enum_indexed_array);
77572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (summary < 0 ||
77672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      summary >= sync_api::SyncManager::Status::SUMMARY_STATUS_COUNT) {
77772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    LOG(DFATAL) << "Illegal Summary Value: " << summary;
77872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return "UNKNOWN";
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
78072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return strings[summary];
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ProfileSyncService::unrecoverable_error_detected() const {
78421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return unrecoverable_error_detected_;
78521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
78621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstring16 ProfileSyncService::GetLastSyncedTimeString() const {
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (last_synced_time_.is_null())
7893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return l10n_util::GetStringUTF16(IDS_SYNC_TIME_NEVER);
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeDelta last_synced = base::Time::Now() - last_synced_time_;
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (last_synced < base::TimeDelta::FromMinutes(1))
7943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return l10n_util::GetStringUTF16(IDS_SYNC_TIME_JUST_NOW);
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return TimeFormat::TimeElapsed(last_synced);
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 ProfileSyncService::GetAuthenticatedUsername() const {
8003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (backend_.get() && backend_initialized_)
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return backend_->GetAuthenticatedUsername();
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return string16();
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnUserSubmittedAuth(
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& username, const std::string& password,
808731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& captcha, const std::string& access_code) {
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_attempted_user_email_ = username;
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_auth_in_progress_ = true;
81172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  auth_start_time_ = base::TimeTicks::Now();
8143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
815201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!signin_.get()) {
816201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // In ChromeOS we sign in during login, so we do not instantiate signin_.
817201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // If this function gets called, we need to re-authenticate (e.g. for
818ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // two factor signin), so instantiate signin_ here.
819201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_.reset(new SigninManager());
820201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_->Initialize(profile_);
8213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
8223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
823731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!access_code.empty()) {
824201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_->ProvideSecondFactorAccessCode(access_code);
825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
828201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!signin_->GetUsername().empty()) {
829201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signin_->SignOut();
8303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
832513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // The user has submitted credentials, which indicates they don't
833513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // want to suppress start up anymore.
834513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  PrefService* prefs = profile_->GetPrefs();
835513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  prefs->SetBoolean(prefs::kSyncSuppressStart, false);
836513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  prefs->ScheduleSavePersistentPrefs();
837513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
838201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  signin_->StartSignIn(username,
839201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                       password,
840201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                       last_auth_error_.captcha().token,
841201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                       captcha);
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnUserChoseDatatypes(bool sync_everything,
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const syncable::ModelTypeSet& chosen_types) {
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!backend_.get()) {
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->SetBoolean(prefs::kKeepEverythingSynced,
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_everything);
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChangePreferredDataTypes(chosen_types);
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->ScheduleSavePersistentPrefs();
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::OnUserCancelledDialog() {
8593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!HasSyncSetupCompleted()) {
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // A sync dialog was aborted before authentication.
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Rollback.
8623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    expect_sync_configuration_aborted_ = true;
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DisableForUser();
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Though an auth could still be in progress, once the dialog is closed we
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // don't want the UI to stay stuck in the "waiting for authentication" state
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as that could take forever.  We set this to false so the buttons to re-
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // login will appear until either a) the original request finishes and
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // succeeds, calling OnAuthError(NONE), or b) the user clicks the button,
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and tries to re-authenticate. (b) is a little awkward as this second
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // request will get queued behind the first and could wind up "undoing" the
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // good if invalid creds were provided, but it's an edge case and the user
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // can of course get themselves out of it.
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_auth_in_progress_ = false;
87672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NotifyObservers();
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::ChangePreferredDataTypes(
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const syncable::ModelTypeSet& preferred_types) {
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Filter out any datatypes which aren't registered, or for which
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the preference can't be set.
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::ModelTypeSet registered_types;
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetRegisteredDataTypes(&registered_types);
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    syncable::ModelType model_type = syncable::ModelTypeFromInt(i);
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!registered_types.count(model_type))
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
8903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const char* pref_name = GetPrefNameForDataType(model_type);
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!pref_name)
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_->GetPrefs()->SetBoolean(pref_name,
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        preferred_types.count(model_type) != 0);
89521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (syncable::AUTOFILL == model_type) {
89621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      profile_->GetPrefs()->SetBoolean(prefs::kSyncAutofillProfile,
89721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          preferred_types.count(model_type) != 0);
89821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we haven't initialized yet, don't configure the DTM as it could cause
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // association to start before a Directory has even been created.
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (backend_initialized_)
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConfigureDataTypeManager();
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::GetPreferredDataTypes(
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    syncable::ModelTypeSet* preferred_types) const {
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  preferred_types->clear();
9103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (profile_->GetPrefs()->GetBoolean(prefs::kKeepEverythingSynced)) {
91121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    GetRegisteredDataTypes(preferred_types);
9123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
91321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Filter out any datatypes which aren't registered, or for which
91421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // the preference can't be read.
91521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    syncable::ModelTypeSet registered_types;
91621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    GetRegisteredDataTypes(&registered_types);
9173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
9183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      syncable::ModelType model_type = syncable::ModelTypeFromInt(i);
9193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (!registered_types.count(model_type))
9203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        continue;
92121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (model_type == syncable::AUTOFILL_PROFILE)
92221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        continue;
9233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const char* pref_name = GetPrefNameForDataType(model_type);
9243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (!pref_name)
9253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        continue;
92621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
92721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // We are trying to group autofill_profile tag with the same
92821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // enabled/disabled state as autofill. Because the UI only shows autofill.
92921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (profile_->GetPrefs()->GetBoolean(pref_name)) {
9303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        preferred_types->insert(model_type);
93121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        if (model_type == syncable::AUTOFILL) {
93221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          if (!registered_types.count(syncable::AUTOFILL_PROFILE))
93321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            continue;
93421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          preferred_types->insert(syncable::AUTOFILL_PROFILE);
93521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        }
93621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
9373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::GetRegisteredDataTypes(
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    syncable::ModelTypeSet* registered_types) const {
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registered_types->clear();
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The data_type_controllers_ are determined by command-line flags; that's
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // effectively what controls the values returned here.
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (DataTypeController::TypeMap::const_iterator it =
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       data_type_controllers_.begin();
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != data_type_controllers_.end(); ++it) {
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registered_types->insert((*it).first);
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
953731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ProfileSyncService::IsUsingSecondaryPassphrase() const {
9544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return backend_.get() && (backend_->IsUsingExplicitPassphrase() ||
9554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      (tried_implicit_gaia_remove_when_bug_62103_fixed_ &&
9564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch       observed_passphrase_required_));
957731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
9583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ProfileSyncService::IsCryptographerReady(
960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const sync_api::BaseTransaction* trans) const {
961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return backend_.get() && backend_->IsCryptographerReady(trans);
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSyncBackendHost* ProfileSyncService::GetBackendForTest() {
96572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We don't check |backend_initialized_|; we assume the test class
96672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // knows what it's doing.
96772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return backend_.get();
96872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
96972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::ConfigureDataTypeManager() {
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!data_type_manager_.get()) {
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_type_manager_.reset(
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        factory_->CreateDataTypeManager(backend_.get(),
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        data_type_controllers_));
9753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    registrar_.Add(this,
9763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   NotificationType::SYNC_CONFIGURE_START,
9773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   Source<DataTypeManager>(data_type_manager_.get()));
9783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    registrar_.Add(this,
9793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   NotificationType::SYNC_CONFIGURE_DONE,
9803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   Source<DataTypeManager>(data_type_manager_.get()));
981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // We create the migrator at the same time.
983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    migrator_.reset(
984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new browser_sync::BackendMigrator(this, data_type_manager_.get()));
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  syncable::ModelTypeSet types;
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetPreferredDataTypes(&types);
989dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // We set this special case here since it's the only datatype whose encryption
990dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // status we already know. All others are set after the initial sync
991dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // completes (for now).
992dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // TODO(zea): Implement a better way that uses preferences for which types
993dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // need encryption.
994dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  encrypted_types_.clear();
995dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (types.count(syncable::PASSWORDS) > 0)
996dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    encrypted_types_.insert(syncable::PASSWORDS);
997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (observed_passphrase_required_ && passphrase_required_for_decryption_) {
998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (IsEncryptedDatatypeEnabled()) {
999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // We need a passphrase still. Prompt the user for a passphrase, and
1000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // DataTypeManager::Configure() will get called once the passphrase is
1001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // accepted.
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      OnPassphraseRequired(true);
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // We've been informed that a passphrase is required for decryption, but
1006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // now there are no encrypted data types enabled, so clear the flag
1007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // (NotifyObservers() will be called when configuration completes).
1008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      observed_passphrase_required_ = false;
1009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data_type_manager_->Configure(types);
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensync_api::UserShare* ProfileSyncService::GetUserShare() const {
101572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
101672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return backend_->GetUserShare();
101772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
101872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NOTREACHED();
101972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return NULL;
102072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
102172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
102272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst browser_sync::sessions::SyncSessionSnapshot*
102372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ProfileSyncService::GetLastSessionSnapshot() const {
102472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
102572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return backend_->GetLastSessionSnapshot();
102672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
102772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NOTREACHED();
102872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return NULL;
102972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
103072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
103172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ProfileSyncService::HasUnsyncedItems() const {
103272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
103372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return backend_->HasUnsyncedItems();
103472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
103572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NOTREACHED();
103672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return false;
103772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
103872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
103972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::GetModelSafeRoutingInfo(
104072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    browser_sync::ModelSafeRoutingInfo* out) {
104172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
104272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    backend_->GetModelSafeRoutingInfo(out);
104372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
104472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NOTREACHED();
104572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
104672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
104772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
104872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensyncable::AutofillMigrationState
104972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ProfileSyncService::GetAutofillMigrationState() {
105072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
105172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return backend_->GetAutofillMigrationState();
105272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
105372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NOTREACHED();
105472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return syncable::NOT_DETERMINED;
105572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
105672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
105772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::SetAutofillMigrationState(
105872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncable::AutofillMigrationState state) {
105972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
106072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    backend_->SetAutofillMigrationState(state);
106172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
106272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NOTREACHED();
106372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
106472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
106572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
106672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensyncable::AutofillMigrationDebugInfo
106772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ProfileSyncService::GetAutofillMigrationDebugInfo() {
106872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
106972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return backend_->GetAutofillMigrationDebugInfo();
107072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
107172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  NOTREACHED();
107272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  syncable::AutofillMigrationDebugInfo debug_info = { 0 };
107372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return debug_info;
107472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
107572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
107672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ProfileSyncService::SetAutofillMigrationDebugInfo(
107772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set,
107872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const syncable::AutofillMigrationDebugInfo& info) {
107972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (backend_.get() && backend_initialized_) {
108072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    backend_->SetAutofillMigrationDebugInfo(property_to_set, info);
108172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
108272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NOTREACHED();
108372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
108472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
108572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::ActivateDataType(
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DataTypeController* data_type_controller,
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChangeProcessor* change_processor) {
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!backend_.get()) {
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
10933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(backend_initialized_);
109472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  change_processor->Start(profile(), backend_->GetUserShare());
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  backend_->ActivateDataType(data_type_controller, change_processor);
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::DeactivateDataType(
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DataTypeController* data_type_controller,
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ChangeProcessor* change_processor) {
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  change_processor->Stop();
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (backend_.get())
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_->DeactivateDataType(data_type_controller, change_processor);
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid ProfileSyncService::SetPassphrase(const std::string& passphrase,
110772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       bool is_explicit,
110872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       bool is_creation) {
1109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (ShouldPushChanges() || observed_passphrase_required_) {
11104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    backend_->SetPassphrase(passphrase, is_explicit);
1111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (is_explicit) {
1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cached_passphrase_.value = passphrase;
1114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cached_passphrase_.is_explicit = is_explicit;
1115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cached_passphrase_.is_creation = is_creation;
1116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      gaia_password_ = passphrase;
1118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProfileSyncService::EncryptDataTypes(
1123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const syncable::ModelTypeSet& encrypted_types) {
1124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  backend_->EncryptDataTypes(encrypted_types);
1125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProfileSyncService::GetEncryptedDataTypes(
1128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    syncable::ModelTypeSet* encrypted_types) const {
1129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  *encrypted_types = encrypted_types_;
1130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::Observe(NotificationType type,
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 const NotificationSource& source,
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 const NotificationDetails& details) {
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::SYNC_CONFIGURE_START: {
113772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NotifyObservers();
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(sync): Maybe toast?
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::SYNC_CONFIGURE_DONE: {
1142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DataTypeManager::ConfigureResultWithErrorLocation* result_with_location =
1143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          Details<DataTypeManager::ConfigureResultWithErrorLocation>(
1144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              details).ptr();
1145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DataTypeManager::ConfigureResult result = result_with_location->result;
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (result == DataTypeManager::ABORTED &&
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          expect_sync_configuration_aborted_) {
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        expect_sync_configuration_aborted_ = false;
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Clear out the gaia password if it is already there.
1153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      gaia_password_ = std::string();
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (result != DataTypeManager::OK) {
1155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        std::string message = StringPrintf("Sync Configuration failed with %d",
1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            result);
1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        OnUnrecoverableError(*(result_with_location->location), message);
1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cached_passphrase_ = CachedPassphrase();
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // If the user had entered a custom passphrase use it now.
11634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (!cached_passphrase_.value.empty()) {
11643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        // Don't hold on to the passphrase in raw form longer than needed.
11654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        SetPassphrase(cached_passphrase_.value,
116672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                      cached_passphrase_.is_explicit,
116772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                      cached_passphrase_.is_creation);
11684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        cached_passphrase_ = CachedPassphrase();
11693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
11703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // We should never get in a state where we have no encrypted datatypes
1172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // enabled, and yet we still think we require a passphrase.
1173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DCHECK(!(observed_passphrase_required_ &&
1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               passphrase_required_for_decryption_ &&
1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               !IsEncryptedDatatypeEnabled()));
1176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(sync): Less wizard, more toast.
1178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      wizard_.Step(SyncSetupWizard::DONE);
117972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NotifyObservers();
1180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // In the old world, this would be a no-op.  With new syncer thread,
1182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // this is the point where it is safe to switch from config-mode to
1183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // normal operation.
1184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      backend_->StartSyncingWithServer();
11853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
11863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
11873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case NotificationType::SYNC_DATA_TYPES_UPDATED: {
11883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (!HasSyncSetupCompleted()) break;
11893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
11903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      syncable::ModelTypeSet types;
11913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GetPreferredDataTypes(&types);
11923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      OnUserChoseDatatypes(false, types);
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::PREF_CHANGED: {
11963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      std::string* pref_name = Details<std::string>(details).ptr();
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (*pref_name == prefs::kSyncManaged) {
119872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NotifyObservers();
11993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (*pref_sync_managed_) {
1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          DisableForUser();
12013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) {
1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          StartUp();
12033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
12043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
12053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
12063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
12073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case NotificationType::GOOGLE_SIGNIN_SUCCESSFUL: {
12084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      const GoogleServiceSigninSuccessDetails* successful =
12094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          (Details<const GoogleServiceSigninSuccessDetails>(details).ptr());
12104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // We pass 'false' to SetPassphrase to denote that this is an implicit
12114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // request and shouldn't override an explicit one.  Thus, we either
12124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // update the implicit passphrase (idempotent if the passphrase didn't
12134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // actually change), or the user has an explicit passphrase set so this
12144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // becomes a no-op.
12154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      tried_implicit_gaia_remove_when_bug_62103_fixed_ = true;
121672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SetPassphrase(successful->password, false, true);
121772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
121872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // If this signin was to initiate a passphrase migration (on the
121972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // first computer, thus not for decryption), continue the migration.
122072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (passphrase_migration_in_progress_ &&
122172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          !passphrase_required_for_decryption_) {
122272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        wizard_.Step(SyncSetupWizard::PASSPHRASE_MIGRATION);
122372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        passphrase_migration_in_progress_ = false;
122472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
122572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
12273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
12283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case NotificationType::GOOGLE_SIGNIN_FAILED: {
12293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GoogleServiceAuthError error =
12303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          *(Details<const GoogleServiceAuthError>(details).ptr());
12313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      UpdateAuthErrorState(error);
12323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
12333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
12343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case NotificationType::TOKEN_AVAILABLE: {
12353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (AreCredentialsAvailable()) {
12363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (backend_initialized_) {
12373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          backend_->UpdateCredentials(GetCredentials());
12383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
12393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (!profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart))
1241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          StartUp();
12423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
12433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
12443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
12453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case NotificationType::TOKEN_LOADING_FINISHED: {
12463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // If not in Chrome OS, and we have a username without tokens,
12473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // the user will need to signin again, so sign out.
12483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (cros_user_.empty() &&
1249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          !signin_->GetUsername().empty() &&
12503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          !AreCredentialsAvailable()) {
12513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        DisableForUser();
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default: {
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::AddObserver(Observer* observer) {
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observers_.AddObserver(observer);
1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::RemoveObserver(Observer* observer) {
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observers_.RemoveObserver(observer);
1267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ProfileSyncService::HasObserver(Observer* observer) const {
1270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return observers_.HasObserver(observer);
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbrowser_sync::JsFrontend* ProfileSyncService::GetJsFrontend() {
127472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return &js_event_handlers_;
127572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
127672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileSyncService::SyncEvent(SyncEventCodes code) {
1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UMA_HISTOGRAM_ENUMERATION("Sync.EventCodes", code, MAX_SYNC_EVENT_CODE);
1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
1282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProfileSyncService::IsSyncEnabled() {
1283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We have switches::kEnableSync just in case we need to change back to
1284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sync-disabled-by-default on a platform.
1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableSync);
1286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProfileSyncService::IsManaged() {
1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Some tests use ProfileSyncServiceMock which doesn't have a profile.
1290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return profile_ && profile_->GetPrefs()->GetBoolean(prefs::kSyncManaged);
1291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProfileSyncService::ShouldPushChanges() {
1294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // True only after all bootstrapping has succeeded: the sync backend
1295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is initialized, all enabled data types are consistent with one
1296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // another, and no unrecoverable error has transpired.
1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (unrecoverable_error_detected_)
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!data_type_manager_.get())
1301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return data_type_manager_->state() == DataTypeManager::CONFIGURED;
1304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1305