Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/browser/sync/profile_sync_service.cc

Issue 3305003: New authorization framework for sync. ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/profile_sync_service.h" 5 #include "chrome/browser/sync/profile_sync_service.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
(...skipping 12 matching lines...) Expand all
23 #include "chrome/browser/prefs/pref_service.h" 23 #include "chrome/browser/prefs/pref_service.h"
24 #include "chrome/browser/profile.h" 24 #include "chrome/browser/profile.h"
25 #include "chrome/browser/net/gaia/token_service.h" 25 #include "chrome/browser/net/gaia/token_service.h"
26 #include "chrome/browser/sync/engine/syncapi.h" 26 #include "chrome/browser/sync/engine/syncapi.h"
27 #include "chrome/browser/sync/glue/change_processor.h" 27 #include "chrome/browser/sync/glue/change_processor.h"
28 #include "chrome/browser/sync/glue/data_type_controller.h" 28 #include "chrome/browser/sync/glue/data_type_controller.h"
29 #include "chrome/browser/sync/glue/data_type_manager.h" 29 #include "chrome/browser/sync/glue/data_type_manager.h"
30 #include "chrome/browser/sync/glue/session_data_type_controller.h" 30 #include "chrome/browser/sync/glue/session_data_type_controller.h"
31 #include "chrome/browser/sync/profile_sync_factory.h" 31 #include "chrome/browser/sync/profile_sync_factory.h"
32 #include "chrome/browser/sync/syncable/directory_manager.h" 32 #include "chrome/browser/sync/syncable/directory_manager.h"
33 #include "chrome/browser/sync/token_migrator.h"
34 #include "chrome/browser/sync/util/user_settings.h"
33 #include "chrome/common/chrome_switches.h" 35 #include "chrome/common/chrome_switches.h"
36 #include "chrome/common/net/gaia/gaia_constants.h"
34 #include "chrome/common/notification_details.h" 37 #include "chrome/common/notification_details.h"
35 #include "chrome/common/notification_service.h" 38 #include "chrome/common/notification_service.h"
36 #include "chrome/common/notification_source.h" 39 #include "chrome/common/notification_source.h"
37 #include "chrome/common/notification_type.h" 40 #include "chrome/common/notification_type.h"
38 #include "chrome/common/pref_names.h" 41 #include "chrome/common/pref_names.h"
39 #include "chrome/common/time_format.h" 42 #include "chrome/common/time_format.h"
40 #include "grit/generated_resources.h" 43 #include "grit/generated_resources.h"
41 #include "net/base/cookie_monster.h" 44 #include "net/base/cookie_monster.h"
42 45
43 using browser_sync::ChangeProcessor; 46 using browser_sync::ChangeProcessor;
44 using browser_sync::DataTypeController; 47 using browser_sync::DataTypeController;
45 using browser_sync::DataTypeManager; 48 using browser_sync::DataTypeManager;
46 using browser_sync::SyncBackendHost; 49 using browser_sync::SyncBackendHost;
50 using sync_api::SyncCredentials;
47 51
48 typedef GoogleServiceAuthError AuthError; 52 typedef GoogleServiceAuthError AuthError;
49 53
50 const char* ProfileSyncService::kSyncServerUrl = 54 const char* ProfileSyncService::kSyncServerUrl =
51 "https://clients4.google.com/chrome-sync"; 55 "https://clients4.google.com/chrome-sync";
52 56
53 const char* ProfileSyncService::kDevServerUrl = 57 const char* ProfileSyncService::kDevServerUrl =
54 "https://clients4.google.com/chrome-sync/dev"; 58 "https://clients4.google.com/chrome-sync/dev";
55 59
56 ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory, 60 ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory,
57 Profile* profile, 61 Profile* profile,
58 bool bootstrap_sync_authentication) 62 const std::string& cros_user)
59 : last_auth_error_(AuthError::None()), 63 : last_auth_error_(AuthError::None()),
60 factory_(factory), 64 factory_(factory),
61 profile_(profile), 65 profile_(profile),
62 bootstrap_sync_authentication_(bootstrap_sync_authentication), 66 cros_user_(cros_user),
63 sync_service_url_(kDevServerUrl), 67 sync_service_url_(kDevServerUrl),
64 backend_initialized_(false), 68 backend_initialized_(false),
65 expecting_first_run_auth_needed_event_(false),
66 is_auth_in_progress_(false), 69 is_auth_in_progress_(false),
67 ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)), 70 ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)),
68 unrecoverable_error_detected_(false), 71 unrecoverable_error_detected_(false),
69 use_chrome_async_socket_(false), 72 use_chrome_async_socket_(false),
70 notification_method_(browser_sync::kDefaultNotificationMethod), 73 notification_method_(browser_sync::kDefaultNotificationMethod),
71 ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)) { 74 ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)),
75 token_migrator_(NULL) {
72 DCHECK(factory); 76 DCHECK(factory);
73 DCHECK(profile); 77 DCHECK(profile);
74 registrar_.Add(this, 78 registrar_.Add(this,
75 NotificationType::SYNC_CONFIGURE_START, 79 NotificationType::SYNC_CONFIGURE_START,
76 NotificationService::AllSources()); 80 NotificationService::AllSources());
77 registrar_.Add(this, 81 registrar_.Add(this,
78 NotificationType::SYNC_CONFIGURE_DONE, 82 NotificationType::SYNC_CONFIGURE_DONE,
79 NotificationService::AllSources()); 83 NotificationService::AllSources());
80 registrar_.Add(this, 84 registrar_.Add(this,
81 NotificationType::SYNC_PASSPHRASE_REQUIRED, 85 NotificationType::SYNC_PASSPHRASE_REQUIRED,
(...skipping 20 matching lines...) Expand all
102 } 106 }
103 #else 107 #else
104 LOG(INFO) << "Unofficial build, using dev channel sync server."; 108 LOG(INFO) << "Unofficial build, using dev channel sync server.";
105 #endif 109 #endif
106 } 110 }
107 111
108 ProfileSyncService::ProfileSyncService() 112 ProfileSyncService::ProfileSyncService()
109 : last_auth_error_(AuthError::None()), 113 : last_auth_error_(AuthError::None()),
110 factory_(NULL), 114 factory_(NULL),
111 profile_(NULL), 115 profile_(NULL),
112 bootstrap_sync_authentication_(false),
113 sync_service_url_(kSyncServerUrl), 116 sync_service_url_(kSyncServerUrl),
114 backend_initialized_(false), 117 backend_initialized_(false),
115 expecting_first_run_auth_needed_event_(false),
116 is_auth_in_progress_(false), 118 is_auth_in_progress_(false),
117 ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)), 119 ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)),
118 unrecoverable_error_detected_(false), 120 unrecoverable_error_detected_(false),
119 use_chrome_async_socket_(false), 121 use_chrome_async_socket_(false),
120 notification_method_(browser_sync::kDefaultNotificationMethod), 122 notification_method_(browser_sync::kDefaultNotificationMethod),
121 ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)), 123 ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)),
122 expect_sync_configuration_aborted_(false) { 124 expect_sync_configuration_aborted_(false) {
123 } 125 }
124 126
125 ProfileSyncService::~ProfileSyncService() { 127 ProfileSyncService::~ProfileSyncService() {
126 Shutdown(false); 128 Shutdown(false);
127 } 129 }
128 130
131 bool ProfileSyncService::AreCredentialsAvailable() {
132 if (IsManaged()) {
133 return false;
134 }
135
136 if (profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)) {
137 return false;
138 }
139
140 // CrOS user is always logged in. Chrome uses signin_ to check logged in.
141 if (!cros_user_.empty() || !signin_.GetUsername().empty()) {
142 // TODO(chron): Verify CrOS unit test behavior.
143 if (profile()->GetTokenService() &&
144 profile()->GetTokenService()->HasTokenForService(
145 GaiaConstants::kSyncService)) {
146 return true;
147 }
148 }
149 return false;
150 }
151
152 void ProfileSyncService::LoadMigratedCredentials(const std::string& username,
153 const std::string& token) {
154 signin_.SetUsername(username);
155 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, username);
156 profile()->GetTokenService()->OnIssueAuthTokenSuccess(
157 GaiaConstants::kSyncService, token);
158 profile()->GetPrefs()->SetBoolean(prefs::kSyncCredentialsMigrated, true);
159 token_migrator_.reset();
160 }
161
129 void ProfileSyncService::Initialize() { 162 void ProfileSyncService::Initialize() {
130 LOG(INFO) << "Starting ProfileSyncService."; 163 LOG(INFO) << "Starting ProfileSyncService.";
131 InitSettings(); 164 InitSettings();
132 RegisterPreferences(); 165 RegisterPreferences();
133 166
134 // Watch the preference that indicates sync is managed so we can take 167 // Watch the preference that indicates sync is managed so we can take
135 // appropriate action. 168 // appropriate action.
136 pref_sync_managed_.Init(prefs::kSyncManaged, profile_->GetPrefs(), this); 169 pref_sync_managed_.Init(prefs::kSyncManaged, profile_->GetPrefs(), this);
137 170
138 // For now, the only thing we can do through policy is to turn sync off. 171 // For now, the only thing we can do through policy is to turn sync off.
139 if (IsManaged()) { 172 if (IsManaged()) {
140 DisableForUser(); 173 DisableForUser();
141 return; 174 return;
142 } 175 }
143 176
144 if (!profile()->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted)) { 177 RegisterAuthNotifications();
178
179 // In Chrome, we integrate a SigninManager which works with the sync
180 // setup wizard to kick off the TokenService. CrOS does its own plumbing
181 // for the TokenService.
182 if (cros_user_.empty()) {
183 // Will load tokens from DB and broadcast Token events after.
184 signin_.Initialize(profile_);
185 }
186
187 if (!HasSyncSetupCompleted()) {
145 DisableForUser(); // Clean up in case of previous crash / setup abort. 188 DisableForUser(); // Clean up in case of previous crash / setup abort.
189 if (!cros_user_.empty() && AreCredentialsAvailable()) {
190 StartUp(); // Under ChromeOS, just autostart it anyway if creds are here.
191 }
192 } else if (AreCredentialsAvailable()) {
193 // If we have credentials and sync setup finished, autostart the backend.
194 // Note that if we haven't finished setting up sync, backend bring up will
195 // be done by the wizard.
196 StartUp();
197 } else {
198 // Try to migrate the tokens (if that hasn't already succeeded).
199 if (!profile()->GetPrefs()->GetBoolean(prefs::kSyncCredentialsMigrated)) {
200 token_migrator_.reset(new TokenMigrator(this, profile_->GetPath()));
201 token_migrator_->TryMigration();
202 }
203 }
146 204
147 // Automatically start sync in Chromium OS. 205 }
148 if (bootstrap_sync_authentication_ && 206
149 !profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)) { 207 void ProfileSyncService::RegisterAuthNotifications() {
150 // If the LSID is empty, we're in a CrOS UI test that is not testing sync 208 registrar_.Add(this,
151 // behavior, so we don't want the sync service to start. 209 NotificationType::TOKEN_AVAILABLE,
152 if (profile()->GetTokenService() && 210 NotificationService::AllSources());
153 !profile()->GetTokenService()->HasLsid()) { 211 registrar_.Add(this,
154 LOG(WARNING) << "Skipping CrOS sync startup, no LSID present."; 212 NotificationType::TOKEN_LOADING_FINISHED,
155 return; 213 NotificationService::AllSources());
156 } 214 registrar_.Add(this,
157 StartUp(); 215 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL,
158 } 216 NotificationService::AllSources());
159 } else { 217 registrar_.Add(this,
160 StartUp(); 218 NotificationType::GOOGLE_SIGNIN_FAILED,
161 } 219 NotificationService::AllSources());
162 } 220 }
163 221
164 void ProfileSyncService::RegisterDataTypeController( 222 void ProfileSyncService::RegisterDataTypeController(
165 DataTypeController* data_type_controller) { 223 DataTypeController* data_type_controller) {
166 DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U); 224 DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U);
167 data_type_controllers_[data_type_controller->type()] = 225 data_type_controllers_[data_type_controller->type()] =
168 data_type_controller; 226 data_type_controller;
169 } 227 }
170 228
171 browser_sync::SessionModelAssociator* 229 browser_sync::SessionModelAssociator*
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 } 283 }
226 } 284 }
227 285
228 void ProfileSyncService::RegisterPreferences() { 286 void ProfileSyncService::RegisterPreferences() {
229 PrefService* pref_service = profile_->GetPrefs(); 287 PrefService* pref_service = profile_->GetPrefs();
230 if (pref_service->FindPreference(prefs::kSyncLastSyncedTime)) 288 if (pref_service->FindPreference(prefs::kSyncLastSyncedTime))
231 return; 289 return;
232 pref_service->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0); 290 pref_service->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0);
233 pref_service->RegisterBooleanPref(prefs::kSyncHasSetupCompleted, false); 291 pref_service->RegisterBooleanPref(prefs::kSyncHasSetupCompleted, false);
234 pref_service->RegisterBooleanPref(prefs::kSyncSuppressStart, false); 292 pref_service->RegisterBooleanPref(prefs::kSyncSuppressStart, false);
293 pref_service->RegisterBooleanPref(prefs::kSyncCredentialsMigrated, false);
235 294
236 // If you've never synced before, or if you're using Chrome OS, all datatypes 295 // If you've never synced before, or if you're using Chrome OS, all datatypes
237 // are on by default. 296 // are on by default.
238 // TODO(nick): Perhaps a better model would be to always default to false, 297 // TODO(nick): Perhaps a better model would be to always default to false,
239 // and explicitly call SetDataTypes() when the user shows the wizard. 298 // and explicitly call SetDataTypes() when the user shows the wizard.
240 #if defined(OS_CHROMEOS) 299 #if defined(OS_CHROMEOS)
241 bool enable_by_default = true; 300 bool enable_by_default = true;
242 #else 301 #else
243 bool enable_by_default = 302 bool enable_by_default =
244 !pref_service->HasPrefPath(prefs::kSyncHasSetupCompleted); 303 !pref_service->HasPrefPath(prefs::kSyncHasSetupCompleted);
(...skipping 17 matching lines...) Expand all
262 void ProfileSyncService::ClearPreferences() { 321 void ProfileSyncService::ClearPreferences() {
263 PrefService* pref_service = profile_->GetPrefs(); 322 PrefService* pref_service = profile_->GetPrefs();
264 pref_service->ClearPref(prefs::kSyncLastSyncedTime); 323 pref_service->ClearPref(prefs::kSyncLastSyncedTime);
265 pref_service->ClearPref(prefs::kSyncHasSetupCompleted); 324 pref_service->ClearPref(prefs::kSyncHasSetupCompleted);
266 pref_service->ClearPref(prefs::kEncryptionBootstrapToken); 325 pref_service->ClearPref(prefs::kEncryptionBootstrapToken);
267 // TODO(nick): The current behavior does not clear e.g. prefs::kSyncBookmarks. 326 // TODO(nick): The current behavior does not clear e.g. prefs::kSyncBookmarks.
268 // Is that really what we want? 327 // Is that really what we want?
269 pref_service->ScheduleSavePersistentPrefs(); 328 pref_service->ScheduleSavePersistentPrefs();
270 } 329 }
271 330
331 SyncCredentials ProfileSyncService::GetCredentials() {
332 SyncCredentials credentials;
333 credentials.email = !cros_user_.empty() ? cros_user_ : signin_.GetUsername();
334 DCHECK(!credentials.email.empty());
335 TokenService* service = profile_->GetTokenService();
336 credentials.sync_token = service->GetTokenForService(
337 GaiaConstants::kSyncService);
338 return credentials;
339 }
340
272 void ProfileSyncService::InitializeBackend(bool delete_sync_data_folder) { 341 void ProfileSyncService::InitializeBackend(bool delete_sync_data_folder) {
273 if (!backend_.get()) { 342 if (!backend_.get()) {
274 NOTREACHED(); 343 NOTREACHED();
275 return; 344 return;
276 } 345 }
277 346
278 // TODO(akalin): Gather all the command-line-controlled switches 347 // TODO(chron): Reimplement invalidate XMPP login / Sync login
279 // into an Options struct to make passing them down less annoying. 348 // command line switches. Perhaps make it a command
349 // line in the TokenService itself to pass an arbitrary
350 // token.
280 351
281 bool invalidate_sync_login = false;
282 bool invalidate_sync_xmpp_login = false;
283 bool try_ssltcp_first = false; 352 bool try_ssltcp_first = false;
284 #if !defined(NDEBUG) 353 #if !defined(NDEBUG)
285 invalidate_sync_login = CommandLine::ForCurrentProcess()->HasSwitch(
286 switches::kInvalidateSyncLogin);
287 invalidate_sync_xmpp_login = CommandLine::ForCurrentProcess()->HasSwitch(
288 switches::kInvalidateSyncXmppLogin);
289 try_ssltcp_first = CommandLine::ForCurrentProcess()->HasSwitch( 354 try_ssltcp_first = CommandLine::ForCurrentProcess()->HasSwitch(
290 switches::kSyncUseSslTcp); 355 switches::kSyncUseSslTcp);
291 #endif 356 #endif
292 357
293 syncable::ModelTypeSet types; 358 syncable::ModelTypeSet types;
294 // If sync setup hasn't finished, we don't want to initialize routing info 359 // If sync setup hasn't finished, we don't want to initialize routing info
295 // for any data types so that we don't download updates for types that the 360 // for any data types so that we don't download updates for types that the
296 // user chooses not to sync on the first DownloadUpdatesCommand. 361 // user chooses not to sync on the first DownloadUpdatesCommand.
297 if (HasSyncSetupCompleted()) 362 if (HasSyncSetupCompleted()) {
298 GetPreferredDataTypes(&types); 363 GetPreferredDataTypes(&types);
364 }
365
366 SyncCredentials credentials = GetCredentials();
367
299 backend_->Initialize(sync_service_url_, 368 backend_->Initialize(sync_service_url_,
300 types, 369 types,
301 profile_->GetRequestContext(), 370 profile_->GetRequestContext(),
302 profile_->GetTokenService()->GetLsid(), 371 credentials,
303 delete_sync_data_folder, 372 delete_sync_data_folder,
304 invalidate_sync_login,
305 invalidate_sync_xmpp_login,
306 use_chrome_async_socket_, 373 use_chrome_async_socket_,
307 try_ssltcp_first, 374 try_ssltcp_first,
308 notification_method_); 375 notification_method_);
309 } 376 }
310 377
311 void ProfileSyncService::CreateBackend() { 378 void ProfileSyncService::CreateBackend() {
312 backend_.reset( 379 backend_.reset(
313 new SyncBackendHost(this, profile_, profile_->GetPath(), 380 new SyncBackendHost(this, profile_, profile_->GetPath(),
314 data_type_controllers_)); 381 data_type_controllers_));
315 } 382 }
316 383
317 void ProfileSyncService::StartUp() { 384 void ProfileSyncService::StartUp() {
318 // Don't start up multiple times. 385 // Don't start up multiple times.
319 if (backend_.get()) { 386 if (backend_.get()) {
320 LOG(INFO) << "Skipping bringing up backend host."; 387 LOG(INFO) << "Skipping bringing up backend host.";
321 return; 388 return;
322 } 389 }
323 390
324 LOG(INFO) << "ProfileSyncSerivce bringing up backend host."; 391 DCHECK(AreCredentialsAvailable());
392
393 LOG(INFO) << "ProfileSyncService bringing up backend host.";
325 394
326 last_synced_time_ = base::Time::FromInternalValue( 395 last_synced_time_ = base::Time::FromInternalValue(
327 profile_->GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime)); 396 profile_->GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime));
328 397
329 CreateBackend(); 398 CreateBackend();
330 // Initialize the backend. Every time we start up a new SyncBackendHost, 399 // Initialize the backend. Every time we start up a new SyncBackendHost,
331 // we'll want to start from a fresh SyncDB, so delete any old one that might 400 // we'll want to start from a fresh SyncDB, so delete any old one that might
332 // be there. 401 // be there.
333 InitializeBackend(!HasSyncSetupCompleted()); 402 InitializeBackend(!HasSyncSetupCompleted());
334 } 403 }
(...skipping 13 matching lines...) Expand all
348 417
349 if (doomed_backend.get()) 418 if (doomed_backend.get())
350 doomed_backend->Shutdown(sync_disabled); 419 doomed_backend->Shutdown(sync_disabled);
351 420
352 doomed_backend.reset(); 421 doomed_backend.reset();
353 422
354 423
355 // Clear various flags. 424 // Clear various flags.
356 is_auth_in_progress_ = false; 425 is_auth_in_progress_ = false;
357 backend_initialized_ = false; 426 backend_initialized_ = false;
358 expecting_first_run_auth_needed_event_ = false;
359 last_attempted_user_email_.clear(); 427 last_attempted_user_email_.clear();
360 } 428 }
361 429
362 void ProfileSyncService::EnableForUser(gfx::NativeWindow parent_window) { 430 void ProfileSyncService::DisableForUser() {
363 if (WizardIsVisible()) { 431 LOG(INFO) << "Disabling sync for user.";
364 wizard_.Focus();
365 return;
366 }
367 expecting_first_run_auth_needed_event_ = true;
368 DCHECK(!data_type_manager_.get());
369 432
370 wizard_.SetParent(parent_window); 433 // Clear prefs (including SyncSetupHasCompleted) before shutting down so
371 StartUp();
372 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
373 }
374
375 void ProfileSyncService::DisableForUser() {
376 LOG(INFO) << "Clearing Sync DB.";
377
378 // Clear prefs (including SyncSetupHasCompleted) before shutting down so
379 // PSS clients don't think we're set up while we're shutting down. 434 // PSS clients don't think we're set up while we're shutting down.
380 ClearPreferences(); 435 ClearPreferences();
381 Shutdown(true); 436 Shutdown(true);
382 437
438 if (cros_user_.empty()) {
439 signin_.SignOut();
440 }
441
383 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 442 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
384 } 443 }
385 444
386 bool ProfileSyncService::HasSyncSetupCompleted() const { 445 bool ProfileSyncService::HasSyncSetupCompleted() const {
387 return profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted); 446 return profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted);
388 } 447 }
389 448
390 void ProfileSyncService::SetSyncSetupCompleted() { 449 void ProfileSyncService::SetSyncSetupCompleted() {
391 PrefService* prefs = profile()->GetPrefs(); 450 PrefService* prefs = profile()->GetPrefs();
392 prefs->SetBoolean(prefs::kSyncHasSetupCompleted, true); 451 prefs->SetBoolean(prefs::kSyncHasSetupCompleted, true);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 void ProfileSyncService::OnUnrecoverableError( 493 void ProfileSyncService::OnUnrecoverableError(
435 const tracked_objects::Location& from_here, 494 const tracked_objects::Location& from_here,
436 const std::string& message) { 495 const std::string& message) {
437 unrecoverable_error_detected_ = true; 496 unrecoverable_error_detected_ = true;
438 unrecoverable_error_message_ = message; 497 unrecoverable_error_message_ = message;
439 unrecoverable_error_location_.reset( 498 unrecoverable_error_location_.reset(
440 new tracked_objects::Location(from_here.function_name(), 499 new tracked_objects::Location(from_here.function_name(),
441 from_here.file_name(), 500 from_here.file_name(),
442 from_here.line_number())); 501 from_here.line_number()));
443 502
444 // Shut all data types down.
445 if (data_type_manager_.get())
446 data_type_manager_->Stop();
447
448 // Tell the wizard so it can inform the user only if it is already open. 503 // Tell the wizard so it can inform the user only if it is already open.
449 wizard_.Step(SyncSetupWizard::FATAL_ERROR); 504 wizard_.Step(SyncSetupWizard::FATAL_ERROR);
450 505
451 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 506 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
452 LOG(ERROR) << "Unrecoverable error detected -- ProfileSyncService unusable."; 507 LOG(ERROR) << "Unrecoverable error detected -- ProfileSyncService unusable."
508 << message;
453 std::string location; 509 std::string location;
454 from_here.Write(true, true, &location); 510 from_here.Write(true, true, &location);
455 LOG(ERROR) << location; 511 LOG(ERROR) << location;
456 512
457 if (SetupInProgress()) { 513 // Shut all data types down.
458 // We've hit an error in the middle of a startup process- shutdown all the 514 MessageLoop::current()->PostTask(FROM_HERE,
459 // backend stuff, and then restart it, so we're in the same state as before.
460 MessageLoop::current()->PostTask(FROM_HERE,
461 scoped_runnable_method_factory_.NewRunnableMethod( 515 scoped_runnable_method_factory_.NewRunnableMethod(
462 &ProfileSyncService::Shutdown, true)); 516 &ProfileSyncService::Shutdown, true));
463 MessageLoop::current()->PostTask(FROM_HERE,
464 scoped_runnable_method_factory_.NewRunnableMethod(
465 &ProfileSyncService::StartUp));
466 }
467 } 517 }
468 518
469 void ProfileSyncService::OnBackendInitialized() { 519 void ProfileSyncService::OnBackendInitialized() {
470 backend_initialized_ = true; 520 backend_initialized_ = true;
471 521
472 // The very first time the backend initializes is effectively the first time 522 // The very first time the backend initializes is effectively the first time
473 // we can say we successfully "synced". last_synced_time_ will only be null 523 // we can say we successfully "synced". last_synced_time_ will only be null
474 // in this case, because the pref wasn't restored on StartUp. 524 // in this case, because the pref wasn't restored on StartUp.
475 if (last_synced_time_.is_null()) 525 if (last_synced_time_.is_null()) {
476 UpdateLastSyncedTime(); 526 UpdateLastSyncedTime();
527 }
477 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 528 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
478 529
479 if (bootstrap_sync_authentication_) { 530 if (!cros_user_.empty()) {
480 if (profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)) { 531 if (profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)) {
481 ShowChooseDataTypes(NULL); 532 ShowChooseDataTypes(NULL);
482 } else { 533 } else {
483 SetSyncSetupCompleted(); 534 SetSyncSetupCompleted();
484 } 535 }
485 } 536 }
486 537
487 if (HasSyncSetupCompleted()) 538 if (HasSyncSetupCompleted()) {
488 ConfigureDataTypeManager(); 539 ConfigureDataTypeManager();
540 }
489 } 541 }
490 542
491 void ProfileSyncService::OnSyncCycleCompleted() { 543 void ProfileSyncService::OnSyncCycleCompleted() {
492 UpdateLastSyncedTime(); 544 UpdateLastSyncedTime();
493 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 545 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
494 } 546 }
495 547
496 void ProfileSyncService::OnAuthError() { 548 void ProfileSyncService::UpdateAuthErrorState(
497 last_auth_error_ = backend_->GetAuthError(); 549 const GoogleServiceAuthError& error) {
550 last_auth_error_ = error;
498 // Protect against the in-your-face dialogs that pop out of nowhere. 551 // Protect against the in-your-face dialogs that pop out of nowhere.
499 // Require the user to click somewhere to run the setup wizard in the case 552 // Require the user to click somewhere to run the setup wizard in the case
500 // of a steady-state auth failure. 553 // of a steady-state auth failure.
501 if (WizardIsVisible() || expecting_first_run_auth_needed_event_) { 554 if (WizardIsVisible()) {
502 wizard_.Step(AuthError::NONE == last_auth_error_.state() ? 555 wizard_.Step(AuthError::NONE == last_auth_error_.state() ?
503 SyncSetupWizard::GAIA_SUCCESS : SyncSetupWizard::GAIA_LOGIN); 556 SyncSetupWizard::GAIA_SUCCESS : SyncSetupWizard::GAIA_LOGIN);
504 } 557 } else {
505
506 if (expecting_first_run_auth_needed_event_) {
507 last_auth_error_ = AuthError::None();
508 expecting_first_run_auth_needed_event_ = false;
509 }
510
511 if (!WizardIsVisible()) {
512 auth_error_time_ == base::TimeTicks::Now(); 558 auth_error_time_ == base::TimeTicks::Now();
513 } 559 }
514 560
515 if (!auth_start_time_.is_null()) { 561 if (!auth_start_time_.is_null()) {
516 UMA_HISTOGRAM_TIMES("Sync.AuthorizationTimeInNetwork", 562 UMA_HISTOGRAM_TIMES("Sync.AuthorizationTimeInNetwork",
517 base::TimeTicks::Now() - auth_start_time_); 563 base::TimeTicks::Now() - auth_start_time_);
518 auth_start_time_ = base::TimeTicks(); 564 auth_start_time_ = base::TimeTicks();
519 } 565 }
520 566
521 is_auth_in_progress_ = false; 567 is_auth_in_progress_ = false;
522 // Fan the notification out to interested UI-thread components. 568 // Fan the notification out to interested UI-thread components.
523 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 569 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
524 } 570 }
525 571
572 void ProfileSyncService::OnAuthError() {
573 UpdateAuthErrorState(backend_->GetAuthError());
574 }
575
526 void ProfileSyncService::OnStopSyncingPermanently() { 576 void ProfileSyncService::OnStopSyncingPermanently() {
527 if (SetupInProgress()) { 577 if (SetupInProgress()) {
528 wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR); 578 wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
529 expect_sync_configuration_aborted_ = true; 579 expect_sync_configuration_aborted_ = true;
530 } 580 }
531 profile_->GetPrefs()->SetBoolean(prefs::kSyncSuppressStart, true); 581 profile_->GetPrefs()->SetBoolean(prefs::kSyncSuppressStart, true);
532 DisableForUser(); 582 DisableForUser();
533 } 583 }
534 584
535 void ProfileSyncService::ShowLoginDialog(gfx::NativeWindow parent_window) { 585 void ProfileSyncService::ShowLoginDialog(gfx::NativeWindow parent_window) {
586 // TODO(johnnyg): File a bug to make sure this doesn't happen.
587 if (!cros_user_.empty()) {
588 LOG(WARNING) << "ShowLoginDialog called on Chrome OS.";
589 return;
590 }
591
536 if (WizardIsVisible()) { 592 if (WizardIsVisible()) {
537 wizard_.Focus(); 593 wizard_.Focus();
538 return; 594 return;
539 } 595 }
540 596
541 if (!auth_error_time_.is_null()) { 597 if (!auth_error_time_.is_null()) {
542 UMA_HISTOGRAM_LONG_TIMES("Sync.ReauthorizationTime", 598 UMA_HISTOGRAM_LONG_TIMES("Sync.ReauthorizationTime",
543 base::TimeTicks::Now() - auth_error_time_); 599 base::TimeTicks::Now() - auth_error_time_);
544 auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null. 600 auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null.
545 } 601 }
546 602
547 if (last_auth_error_.state() != AuthError::NONE) { 603 wizard_.SetParent(parent_window);
548 wizard_.SetParent(parent_window); 604 wizard_.Step(SyncSetupWizard::GAIA_LOGIN);
549 wizard_.Step(SyncSetupWizard::GAIA_LOGIN); 605
550 } 606 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
551 } 607 }
552 608
553 void ProfileSyncService::ShowChooseDataTypes(gfx::NativeWindow parent_window) { 609 void ProfileSyncService::ShowChooseDataTypes(gfx::NativeWindow parent_window) {
554 if (WizardIsVisible()) { 610 if (WizardIsVisible()) {
555 wizard_.Focus(); 611 wizard_.Focus();
556 return; 612 return;
557 } 613 }
558 wizard_.SetParent(parent_window); 614 wizard_.SetParent(parent_window);
559 wizard_.Step(SyncSetupWizard::CHOOSE_DATA_TYPES); 615 wizard_.Step(SyncSetupWizard::CHOOSE_DATA_TYPES);
560 } 616 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 string16 ProfileSyncService::GetAuthenticatedUsername() const { 672 string16 ProfileSyncService::GetAuthenticatedUsername() const {
617 if (backend_.get() && backend_initialized_) 673 if (backend_.get() && backend_initialized_)
618 return backend_->GetAuthenticatedUsername(); 674 return backend_->GetAuthenticatedUsername();
619 else 675 else
620 return string16(); 676 return string16();
621 } 677 }
622 678
623 void ProfileSyncService::OnUserSubmittedAuth( 679 void ProfileSyncService::OnUserSubmittedAuth(
624 const std::string& username, const std::string& password, 680 const std::string& username, const std::string& password,
625 const std::string& captcha) { 681 const std::string& captcha) {
626 if (!backend_.get()) {
627 NOTREACHED();
628 return;
629 }
630 last_attempted_user_email_ = username; 682 last_attempted_user_email_ = username;
631 is_auth_in_progress_ = true; 683 is_auth_in_progress_ = true;
632 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 684 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
633 685
634 auth_start_time_ = base::TimeTicks::Now(); 686 auth_start_time_ = base::TimeTicks::Now();
635 backend_->Authenticate(username, password, captcha); 687
688 // TODO(chron): Mechanism for ChromeOS auth renewal?
689 // (maybe just run the dialog anyway?)
690 // or send it to the CrOS login somehow?
691 if (!cros_user_.empty()) {
692 LOG(WARNING) << "No mechanism on ChromeOS yet. See http://crbug.com/50292";
693 }
694
695 if (!signin_.GetUsername().empty()) {
696 signin_.SignOut();
697 }
698 signin_.StartSignIn(username,
699 password,
700 last_auth_error_.captcha().token,
701 captcha);
636 } 702 }
637 703
638 void ProfileSyncService::OnUserChoseDatatypes(bool sync_everything, 704 void ProfileSyncService::OnUserChoseDatatypes(bool sync_everything,
639 const syncable::ModelTypeSet& chosen_types) { 705 const syncable::ModelTypeSet& chosen_types) {
640 if (!backend_.get()) { 706 if (!backend_.get()) {
641 NOTREACHED(); 707 NOTREACHED();
642 return; 708 return;
643 } 709 }
644 profile_->GetPrefs()->SetBoolean(prefs::kKeepEverythingSynced, 710 profile_->GetPrefs()->SetBoolean(prefs::kKeepEverythingSynced,
645 sync_everything); 711 sync_everything);
646 712
647 ChangePreferredDataTypes(chosen_types); 713 ChangePreferredDataTypes(chosen_types);
648 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); 714 profile_->GetPrefs()->ScheduleSavePersistentPrefs();
649 } 715 }
650 716
651 void ProfileSyncService::OnUserCancelledDialog() { 717 void ProfileSyncService::OnUserCancelledDialog() {
652 if (!profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted)) { 718 if (!HasSyncSetupCompleted()) {
653 // A sync dialog was aborted before authentication. 719 // A sync dialog was aborted before authentication.
654 // Rollback. 720 // Rollback.
655 expect_sync_configuration_aborted_ = true; 721 expect_sync_configuration_aborted_ = true;
656 DisableForUser(); 722 DisableForUser();
657 } 723 }
658 wizard_.SetParent(NULL); 724 wizard_.SetParent(NULL);
659 725
660 // Though an auth could still be in progress, once the dialog is closed we 726 // Though an auth could still be in progress, once the dialog is closed we
661 // don't want the UI to stay stuck in the "waiting for authentication" state 727 // don't want the UI to stay stuck in the "waiting for authentication" state
662 // as that could take forever. We set this to false so the buttons to re- 728 // as that could take forever. We set this to false so the buttons to re-
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 GetPreferredDataTypes(&types); 874 GetPreferredDataTypes(&types);
809 data_type_manager_->Configure(types); 875 data_type_manager_->Configure(types);
810 876
811 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 877 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
812 break; 878 break;
813 } 879 }
814 case NotificationType::PREF_CHANGED: { 880 case NotificationType::PREF_CHANGED: {
815 std::string* pref_name = Details<std::string>(details).ptr(); 881 std::string* pref_name = Details<std::string>(details).ptr();
816 if (*pref_name == prefs::kSyncManaged) { 882 if (*pref_name == prefs::kSyncManaged) {
817 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged()); 883 FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
818 if (*pref_sync_managed_) 884 if (*pref_sync_managed_) {
819 DisableForUser(); 885 DisableForUser();
820 else if (HasSyncSetupCompleted()) 886 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) {
821 StartUp(); 887 StartUp();
888 }
889 }
890 break;
891 }
892 case NotificationType::GOOGLE_SIGNIN_SUCCESSFUL: {
893 LOG(INFO) << "Signin OK. Waiting on tokens.";
894 // TODO(chron): UI update?
895 // TODO(chron): Timeout?
896 break;
897 }
898 case NotificationType::GOOGLE_SIGNIN_FAILED: {
899 GoogleServiceAuthError error =
900 *(Details<GoogleServiceAuthError>(details).ptr());
901 UpdateAuthErrorState(error);
902 break;
903 }
904 case NotificationType::TOKEN_AVAILABLE: {
905 if (AreCredentialsAvailable()) {
906 if (backend_initialized_) {
907 backend_->UpdateCredentials(GetCredentials());
908 }
909
910 StartUp();
911 }
912 break;
913 }
914 case NotificationType::TOKEN_LOADING_FINISHED: {
915 // If not in Chrome OS, and we have a username without tokens,
916 // the user will need to signin again, so sign out.
917 if (cros_user_.empty() &&
918 !signin_.GetUsername().empty() &&
919 !AreCredentialsAvailable()) {
920 DisableForUser();
822 } 921 }
823 break; 922 break;
824 } 923 }
825 default: { 924 default: {
826 NOTREACHED(); 925 NOTREACHED();
827 } 926 }
828 } 927 }
829 } 928 }
830 929
831 void ProfileSyncService::AddObserver(Observer* observer) { 930 void ProfileSyncService::AddObserver(Observer* observer) {
(...skipping 25 matching lines...) Expand all
857 // is initialized, all enabled data types are consistent with one 956 // is initialized, all enabled data types are consistent with one
858 // another, and no unrecoverable error has transpired. 957 // another, and no unrecoverable error has transpired.
859 if (unrecoverable_error_detected_) 958 if (unrecoverable_error_detected_)
860 return false; 959 return false;
861 960
862 if (!data_type_manager_.get()) 961 if (!data_type_manager_.get())
863 return false; 962 return false;
864 963
865 return data_type_manager_->state() == DataTypeManager::CONFIGURED; 964 return data_type_manager_->state() == DataTypeManager::CONFIGURED;
866 } 965 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698