OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <cstddef> | 7 #include <cstddef> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { | 285 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { |
286 return; | 286 return; |
287 } | 287 } |
288 | 288 |
289 // If sync setup has completed we always start the backend. If the user is in | 289 // If sync setup has completed we always start the backend. If the user is in |
290 // the process of setting up now, we should start the backend to download | 290 // the process of setting up now, we should start the backend to download |
291 // account control state / encryption information). If autostart is enabled, | 291 // account control state / encryption information). If autostart is enabled, |
292 // but we haven't completed sync setup, we try to start sync anyway, since | 292 // but we haven't completed sync setup, we try to start sync anyway, since |
293 // it's possible we crashed/shutdown after logging in but before the backend | 293 // it's possible we crashed/shutdown after logging in but before the backend |
294 // finished initializing the last time. | 294 // finished initializing the last time. |
295 if (!HasSyncSetupCompleted() && !setup_in_progress_ && !auto_start_enabled_) | 295 // |
296 return; | 296 // However, the only time we actually need to start sync _immediately_ is if |
297 | 297 // we haven't completed sync setup and the user is in the process of setting |
298 // All systems Go for launch. | 298 // up - either they just signed in (for the first time) on an auto-start |
299 StartUp(); | 299 // platform or they explicitly kicked off sync setup, and e.g we need to |
| 300 // fetch account details like encryption state to populate UI. Otherwise, |
| 301 // for performance reasons and maximizing parallelism at chrome startup, we |
| 302 // defer the heavy lifting for sync init until things have calmed down. |
| 303 if (HasSyncSetupCompleted()) { |
| 304 StartUp(STARTUP_BACKEND_DEFERRED); |
| 305 } else if (setup_in_progress_ || auto_start_enabled_) { |
| 306 // We haven't completed sync setup. Start immediately if the user explicitly |
| 307 // kicked this off or we're supposed to automatically start syncing. |
| 308 StartUp(STARTUP_IMMEDIATE); |
| 309 } |
300 } | 310 } |
301 | 311 |
302 void ProfileSyncService::StartSyncingWithServer() { | 312 void ProfileSyncService::StartSyncingWithServer() { |
303 if (backend_.get()) | 313 if (backend_.get()) |
304 backend_->StartSyncingWithServer(); | 314 backend_->StartSyncingWithServer(); |
305 } | 315 } |
306 | 316 |
307 void ProfileSyncService::RegisterAuthNotifications() { | 317 void ProfileSyncService::RegisterAuthNotifications() { |
308 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 318 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
309 registrar_.Add(this, | 319 registrar_.Add(this, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 | 465 |
456 void ProfileSyncService::OnSyncConfigureRetry() { | 466 void ProfileSyncService::OnSyncConfigureRetry() { |
457 // Note: in order to handle auth failures that arise before the backend is | 467 // Note: in order to handle auth failures that arise before the backend is |
458 // initialized (e.g. from invalidation notifier, or downloading new control | 468 // initialized (e.g. from invalidation notifier, or downloading new control |
459 // types), we have to gracefully handle configuration retries at all times. | 469 // types), we have to gracefully handle configuration retries at all times. |
460 // At this point an auth error badge should be shown, which once resolved | 470 // At this point an auth error badge should be shown, which once resolved |
461 // will trigger a new sync cycle. | 471 // will trigger a new sync cycle. |
462 NotifyObservers(); | 472 NotifyObservers(); |
463 } | 473 } |
464 | 474 |
465 | 475 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { |
466 void ProfileSyncService::StartUp() { | |
467 // Don't start up multiple times. | 476 // Don't start up multiple times. |
468 if (backend_.get()) { | 477 if (backend_.get()) { |
469 DVLOG(1) << "Skipping bringing up backend host."; | 478 DVLOG(1) << "Skipping bringing up backend host."; |
470 return; | 479 return; |
471 } | 480 } |
472 | 481 |
473 DCHECK(IsSyncEnabledAndLoggedIn()); | 482 DCHECK(IsSyncEnabledAndLoggedIn()); |
474 | 483 |
475 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); | 484 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); |
| 485 |
| 486 DCHECK(start_up_time_.is_null()); |
476 start_up_time_ = base::Time::Now(); | 487 start_up_time_ = base::Time::Now(); |
477 | 488 |
478 #if defined(OS_CHROMEOS) | 489 #if defined(OS_CHROMEOS) |
479 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); | 490 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); |
480 if (bootstrap_token.empty()) { | 491 if (bootstrap_token.empty()) { |
481 sync_prefs_.SetEncryptionBootstrapToken( | 492 sync_prefs_.SetEncryptionBootstrapToken( |
482 sync_prefs_.GetSpareBootstrapToken()); | 493 sync_prefs_.GetSpareBootstrapToken()); |
483 } | 494 } |
484 #endif | 495 #endif |
| 496 |
| 497 if (!sync_global_error_.get()) { |
| 498 #if !defined(OS_ANDROID) |
| 499 sync_global_error_.reset(new SyncGlobalError(this, signin())); |
| 500 #endif |
| 501 GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError( |
| 502 sync_global_error_.get()); |
| 503 AddObserver(sync_global_error_.get()); |
| 504 } |
| 505 |
| 506 if (deferred_option == STARTUP_BACKEND_DEFERRED && |
| 507 CommandLine::ForCurrentProcess()-> |
| 508 HasSwitch(switches::kSyncEnableDeferredStartup)) { |
| 509 return; |
| 510 } |
| 511 |
| 512 StartUpSlowBackendComponents(STARTUP_IMMEDIATE); |
| 513 } |
| 514 |
| 515 void ProfileSyncService::StartUpSlowBackendComponents( |
| 516 StartUpDeferredOption deferred_option) { |
| 517 // Don't start up multiple times. |
| 518 if (backend_.get()) { |
| 519 DVLOG(1) << "Skipping bringing up backend host."; |
| 520 return; |
| 521 } |
| 522 |
| 523 DCHECK(!start_up_time_.is_null()); |
| 524 if (deferred_option == STARTUP_BACKEND_DEFERRED) { |
| 525 base::TimeDelta time_deferred = base::Time::Now() - start_up_time_; |
| 526 UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred); |
| 527 } |
| 528 |
| 529 DCHECK(IsSyncEnabledAndLoggedIn()); |
485 CreateBackend(); | 530 CreateBackend(); |
486 | 531 |
487 // Initialize the backend. Every time we start up a new SyncBackendHost, | 532 // Initialize the backend. Every time we start up a new SyncBackendHost, |
488 // we'll want to start from a fresh SyncDB, so delete any old one that might | 533 // we'll want to start from a fresh SyncDB, so delete any old one that might |
489 // be there. | 534 // be there. |
490 InitializeBackend(!HasSyncSetupCompleted()); | 535 InitializeBackend(!HasSyncSetupCompleted()); |
491 | 536 |
492 // |backend_| may end up being NULL here in tests (in synchronous | 537 // |backend_| may end up being NULL here in tests (in synchronous |
493 // initialization mode). | 538 // initialization mode). |
494 // | 539 // |
495 // TODO(akalin): Fix this horribly non-intuitive behavior (see | 540 // TODO(akalin): Fix this horribly non-intuitive behavior (see |
496 // http://crbug.com/140354). | 541 // http://crbug.com/140354). |
497 if (backend_.get()) { | 542 if (backend_.get()) { |
498 backend_->UpdateRegisteredInvalidationIds( | 543 backend_->UpdateRegisteredInvalidationIds( |
499 invalidator_registrar_->GetAllRegisteredIds()); | 544 invalidator_registrar_->GetAllRegisteredIds()); |
500 } | 545 } |
501 | |
502 if (!sync_global_error_.get()) { | |
503 #if !defined(OS_ANDROID) | |
504 sync_global_error_.reset(new SyncGlobalError(this, signin())); | |
505 #endif | |
506 GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError( | |
507 sync_global_error_.get()); | |
508 AddObserver(sync_global_error_.get()); | |
509 } | |
510 } | 546 } |
511 | 547 |
512 void ProfileSyncService::RegisterInvalidationHandler( | 548 void ProfileSyncService::RegisterInvalidationHandler( |
513 syncer::InvalidationHandler* handler) { | 549 syncer::InvalidationHandler* handler) { |
514 invalidator_registrar_->RegisterHandler(handler); | 550 invalidator_registrar_->RegisterHandler(handler); |
515 } | 551 } |
516 | 552 |
517 void ProfileSyncService::UpdateRegisteredInvalidationIds( | 553 void ProfileSyncService::UpdateRegisteredInvalidationIds( |
518 syncer::InvalidationHandler* handler, | 554 syncer::InvalidationHandler* handler, |
519 const syncer::ObjectIdSet& ids) { | 555 const syncer::ObjectIdSet& ids) { |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 debug_info_listener, | 793 debug_info_listener, |
758 bool success) { | 794 bool success) { |
759 is_first_time_sync_configure_ = !HasSyncSetupCompleted(); | 795 is_first_time_sync_configure_ = !HasSyncSetupCompleted(); |
760 | 796 |
761 if (is_first_time_sync_configure_) { | 797 if (is_first_time_sync_configure_) { |
762 UMA_HISTOGRAM_BOOLEAN("Sync.BackendInitializeFirstTimeSuccess", success); | 798 UMA_HISTOGRAM_BOOLEAN("Sync.BackendInitializeFirstTimeSuccess", success); |
763 } else { | 799 } else { |
764 UMA_HISTOGRAM_BOOLEAN("Sync.BackendInitializeRestoreSuccess", success); | 800 UMA_HISTOGRAM_BOOLEAN("Sync.BackendInitializeRestoreSuccess", success); |
765 } | 801 } |
766 | 802 |
767 if (!start_up_time_.is_null()) { | 803 DCHECK(!start_up_time_.is_null()); |
768 base::Time on_backend_initialized_time = base::Time::Now(); | 804 base::Time on_backend_initialized_time = base::Time::Now(); |
769 base::TimeDelta delta = on_backend_initialized_time - start_up_time_; | 805 base::TimeDelta delta = on_backend_initialized_time - start_up_time_; |
770 if (is_first_time_sync_configure_) { | 806 if (is_first_time_sync_configure_) { |
771 UMA_HISTOGRAM_LONG_TIMES("Sync.BackendInitializeFirstTime", delta); | 807 UMA_HISTOGRAM_LONG_TIMES("Sync.BackendInitializeFirstTime", delta); |
772 } else { | 808 } else { |
773 UMA_HISTOGRAM_LONG_TIMES("Sync.BackendInitializeRestoreTime", delta); | 809 UMA_HISTOGRAM_LONG_TIMES("Sync.BackendInitializeRestoreTime", delta); |
774 } | |
775 start_up_time_ = base::Time(); | |
776 } | 810 } |
| 811 start_up_time_ = base::Time(); |
777 | 812 |
778 if (!success) { | 813 if (!success) { |
779 // Something went unexpectedly wrong. Play it safe: stop syncing at once | 814 // Something went unexpectedly wrong. Play it safe: stop syncing at once |
780 // and surface error UI to alert the user sync has stopped. | 815 // and surface error UI to alert the user sync has stopped. |
781 // Keep the directory around for now so that on restart we will retry | 816 // Keep the directory around for now so that on restart we will retry |
782 // again and potentially succeed in presence of transient file IO failures | 817 // again and potentially succeed in presence of transient file IO failures |
783 // or permissions issues, etc. | 818 // or permissions issues, etc. |
784 // | 819 // |
785 // TODO(rlarocque): Consider making this UnrecoverableError less special. | 820 // TODO(rlarocque): Consider making this UnrecoverableError less special. |
786 // Unlike every other UnrecoverableError, it does not delete our sync data. | 821 // Unlike every other UnrecoverableError, it does not delete our sync data. |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 data_type_manager_.get() && | 1266 data_type_manager_.get() && |
1232 data_type_manager_->state() != DataTypeManager::CONFIGURED) { | 1267 data_type_manager_->state() != DataTypeManager::CONFIGURED) { |
1233 return "Datatypes not fully initialized"; | 1268 return "Datatypes not fully initialized"; |
1234 } else if (ShouldPushChanges()) { | 1269 } else if (ShouldPushChanges()) { |
1235 return "Sync service initialized"; | 1270 return "Sync service initialized"; |
1236 } else { | 1271 } else { |
1237 return "Status unknown: Internal error?"; | 1272 return "Status unknown: Internal error?"; |
1238 } | 1273 } |
1239 } | 1274 } |
1240 | 1275 |
| 1276 std::string ProfileSyncService::GetBackendInitializationStateString() const { |
| 1277 if (sync_initialized()) |
| 1278 return "Done"; |
| 1279 else if (!start_up_time_.is_null()) |
| 1280 return "Deferred"; |
| 1281 else |
| 1282 return "Not started"; |
| 1283 } |
| 1284 |
1241 bool ProfileSyncService::QueryDetailedSyncStatus( | 1285 bool ProfileSyncService::QueryDetailedSyncStatus( |
1242 SyncBackendHost::Status* result) { | 1286 SyncBackendHost::Status* result) { |
1243 if (backend_.get() && backend_initialized_) { | 1287 if (backend_.get() && backend_initialized_) { |
1244 *result = backend_->GetDetailedStatus(); | 1288 *result = backend_->GetDetailedStatus(); |
1245 return true; | 1289 return true; |
1246 } else { | 1290 } else { |
1247 SyncBackendHost::Status status; | 1291 SyncBackendHost::Status status; |
1248 status.sync_protocol_error = last_actionable_error_; | 1292 status.sync_protocol_error = last_actionable_error_; |
1249 *result = status; | 1293 *result = status; |
1250 return false; | 1294 return false; |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 // See http://stackoverflow.com/questions/6224121/is-new-this-myclass-undefine
d-behaviour-after-directly-calling-the-destru. | 2006 // See http://stackoverflow.com/questions/6224121/is-new-this-myclass-undefine
d-behaviour-after-directly-calling-the-destru. |
1963 ProfileSyncService* old_this = this; | 2007 ProfileSyncService* old_this = this; |
1964 this->~ProfileSyncService(); | 2008 this->~ProfileSyncService(); |
1965 new(old_this) ProfileSyncService( | 2009 new(old_this) ProfileSyncService( |
1966 new ProfileSyncComponentsFactoryImpl(profile, | 2010 new ProfileSyncComponentsFactoryImpl(profile, |
1967 CommandLine::ForCurrentProcess()), | 2011 CommandLine::ForCurrentProcess()), |
1968 profile, | 2012 profile, |
1969 signin, | 2013 signin, |
1970 behavior); | 2014 behavior); |
1971 } | 2015 } |
OLD | NEW |