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

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

Issue 12288010: sync: preliminary support for deferred SyncBackendHost initialization (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: dchecks Created 7 years, 9 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
« no previous file with comments | « chrome/browser/sync/profile_sync_service.h ('k') | chrome/common/chrome_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/sync/profile_sync_service.h ('k') | chrome/common/chrome_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698