summaryrefslogtreecommitdiff
path: root/chrome/browser/sync/profile_sync_service.cc
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-05-09 18:35:53 +0100
committerTorne (Richard Coles) <torne@google.com>2013-05-13 13:57:14 +0100
commitc2e0dbddbe15c98d52c4786dac06cb8952a8ae6d (patch)
tree1dbdbb0624cc869ab25ee7f46971984c6fee3e7a /chrome/browser/sync/profile_sync_service.cc
parent2d519ce2457219605d4f472da8d2ffd469796035 (diff)
downloadchromium_org-c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d.tar.gz
Merge from Chromium at DEPS revision r198571
This commit was generated by merge_to_master.py. Change-Id: I951118a03836157090561764dd2627f0add8118f
Diffstat (limited to 'chrome/browser/sync/profile_sync_service.cc')
-rw-r--r--chrome/browser/sync/profile_sync_service.cc192
1 files changed, 141 insertions, 51 deletions
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 8db6c45147..2be7544bc5 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -28,6 +28,8 @@
#include "chrome/browser/net/chrome_cookie_notification_details.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/about_signin_internals.h"
+#include "chrome/browser/signin/about_signin_internals_factory.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/signin/token_service.h"
@@ -130,7 +132,7 @@ bool ShouldShowActionOnUI(
ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory,
Profile* profile,
- SigninManager* signin_manager,
+ SigninManagerBase* signin_manager,
StartBehavior start_behavior)
: last_auth_error_(AuthError::AuthErrorNone()),
passphrase_required_reason_(syncer::REASON_PASSPHRASE_NOT_REQUIRED),
@@ -140,18 +142,19 @@ ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory,
sync_prefs_(profile_ ? profile_->GetPrefs() : NULL),
invalidator_storage_(profile_ ? profile_->GetPrefs(): NULL),
sync_service_url_(kDevServerUrl),
+ data_type_requested_sync_startup_(false),
is_first_time_sync_configure_(false),
backend_initialized_(false),
is_auth_in_progress_(false),
signin_(signin_manager),
unrecoverable_error_reason_(ERROR_REASON_UNSET),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_factory_(this),
expect_sync_configuration_aborted_(false),
encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()),
encrypt_everything_(false),
encryption_pending_(false),
auto_start_enabled_(start_behavior == AUTO_START),
- failed_datatypes_handler_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ failed_datatypes_handler_(this),
configure_status_(DataTypeManager::UNKNOWN),
setup_in_progress_(false),
invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR) {
@@ -199,6 +202,10 @@ bool ProfileSyncService::ShouldEnablePasswordSyncForAndroid() const {
sync_prefs_.GetPreferredDataTypes(registered_types);
if (!preferred_types.Has(syncer::PASSWORDS))
return false;
+ // If backend has not completed initializing we cannot check if the
+ // cryptographer is ready.
+ if (!sync_initialized())
+ return false;
// On Android we do not want to prompt user to enter a passphrase. If
// passwords cannot be decrypted we just disable them.
syncer::ReadTransaction trans(FROM_HERE, GetUserShare());
@@ -301,7 +308,12 @@ void ProfileSyncService::TryStart() {
// for performance reasons and maximizing parallelism at chrome startup, we
// defer the heavy lifting for sync init until things have calmed down.
if (HasSyncSetupCompleted()) {
- StartUp(STARTUP_BACKEND_DEFERRED);
+ if (!data_type_requested_sync_startup_)
+ StartUp(STARTUP_BACKEND_DEFERRED);
+ else if (start_up_time_.is_null())
+ StartUp(STARTUP_IMMEDIATE);
+ else
+ StartUpSlowBackendComponents();
} else if (setup_in_progress_ || auto_start_enabled_) {
// We haven't completed sync setup. Start immediately if the user explicitly
// kicked this off or we're supposed to automatically start syncing.
@@ -310,7 +322,7 @@ void ProfileSyncService::TryStart() {
}
void ProfileSyncService::StartSyncingWithServer() {
- if (backend_.get())
+ if (backend_)
backend_->StartSyncingWithServer();
}
@@ -326,6 +338,9 @@ void ProfileSyncService::RegisterAuthNotifications() {
chrome::NOTIFICATION_TOKEN_REQUEST_FAILED,
content::Source<TokenService>(token_service));
registrar_.Add(this,
+ chrome::NOTIFICATION_TOKENS_CLEARED,
+ content::Source<TokenService>(token_service));
+ registrar_.Add(this,
chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
content::Source<Profile>(profile_));
registrar_.Add(this,
@@ -355,13 +370,24 @@ browser_sync::SessionModelAssociator*
scoped_ptr<browser_sync::DeviceInfo>
ProfileSyncService::GetLocalDeviceInfo() const {
- DCHECK(sync_initialized());
- browser_sync::SyncedDeviceTracker* device_tracker =
- backend_->GetSyncedDeviceTracker();
- if (device_tracker)
- return device_tracker->ReadLocalDeviceInfo();
- else
- return scoped_ptr<browser_sync::DeviceInfo>();
+ if (backend_) {
+ browser_sync::SyncedDeviceTracker* device_tracker =
+ backend_->GetSyncedDeviceTracker();
+ if (device_tracker)
+ return device_tracker->ReadLocalDeviceInfo();
+ }
+ return scoped_ptr<browser_sync::DeviceInfo>();
+}
+
+scoped_ptr<browser_sync::DeviceInfo>
+ProfileSyncService::GetDeviceInfo(const std::string& client_id) const {
+ if (backend_) {
+ browser_sync::SyncedDeviceTracker* device_tracker =
+ backend_->GetSyncedDeviceTracker();
+ if (device_tracker)
+ return device_tracker->ReadDeviceInfo(client_id);
+ }
+ return scoped_ptr<browser_sync::DeviceInfo>();
}
void ProfileSyncService::GetDataTypeControllerStates(
@@ -398,8 +424,11 @@ SyncCredentials ProfileSyncService::GetCredentials() {
DCHECK(!credentials.email.empty());
TokenService* service = TokenServiceFactory::GetForProfile(profile_);
if (service->HasTokenForService(GaiaConstants::kSyncService)) {
- credentials.sync_token = service->GetTokenForService(
- GaiaConstants::kSyncService);
+ credentials.sync_token = service->GetTokenForService(
+ GaiaConstants::kSyncService);
+ credentials.sync_token_time =
+ AboutSigninInternalsFactory::GetForProfile(profile_)->
+ GetTokenTime(GaiaConstants::kSyncService);
UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false);
} else {
// We've lost our sync credentials (crbug.com/121755), so just make up some
@@ -411,7 +440,7 @@ SyncCredentials ProfileSyncService::GetCredentials() {
}
void ProfileSyncService::InitializeBackend(bool delete_stale_data) {
- if (!backend_.get()) {
+ if (!backend_) {
NOTREACHED();
return;
}
@@ -474,7 +503,7 @@ void ProfileSyncService::OnSyncConfigureRetry() {
void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) {
// Don't start up multiple times.
- if (backend_.get()) {
+ if (backend_) {
DVLOG(1) << "Skipping bringing up backend host.";
return;
}
@@ -494,7 +523,7 @@ void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) {
}
#endif
- if (!sync_global_error_.get()) {
+ if (!sync_global_error_) {
#if !defined(OS_ANDROID)
sync_global_error_.reset(new SyncGlobalError(this, signin()));
#endif
@@ -509,21 +538,56 @@ void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) {
return;
}
- StartUpSlowBackendComponents(STARTUP_IMMEDIATE);
+ StartUpSlowBackendComponents();
}
-void ProfileSyncService::StartUpSlowBackendComponents(
- StartUpDeferredOption deferred_option) {
- // Don't start up multiple times.
+void ProfileSyncService::OnDataTypeRequestsSyncStartup(
+ syncer::ModelType type) {
+ DCHECK(syncer::UserTypes().Has(type));
if (backend_.get()) {
- DVLOG(1) << "Skipping bringing up backend host.";
+ DVLOG(1) << "A data type requested sync startup, but it looks like "
+ "something else beat it to the punch.";
return;
}
- DCHECK(!start_up_time_.is_null());
- if (deferred_option == STARTUP_BACKEND_DEFERRED) {
- base::TimeDelta time_deferred = base::Time::Now() - start_up_time_;
- UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred);
+ if (!GetPreferredDataTypes().Has(type)) {
+ // We can get here as datatype SyncableServices are typically wired up
+ // to the native datatype even if sync isn't enabled.
+ DVLOG(1) << "Dropping sync startup request because type "
+ << syncer::ModelTypeToString(type) << "not enabled.";
+ return;
+ }
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSyncEnableDeferredStartup)) {
+ DVLOG(2) << "Data type requesting sync startup: "
+ << syncer::ModelTypeToString(type);
+ // Measure the time spent waiting for init and the type that triggered it.
+ // We could measure the time spent deferred on a per-datatype basis, but
+ // for now this is probably sufficient.
+ if (!start_up_time_.is_null()) {
+ // TODO(tim): Cache |type| and move this tracking to StartUp. I'd like
+ // to pull all the complicated init logic and state out of
+ // ProfileSyncService and have only a StartUp method, though. One step
+ // at a time. Bug 80149.
+ base::TimeDelta time_deferred = base::Time::Now() - start_up_time_;
+ UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred);
+ UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit",
+ ModelTypeToHistogramInt(type),
+ syncer::MODEL_TYPE_COUNT);
+ }
+ data_type_requested_sync_startup_ = true;
+ TryStart();
+ }
+ DVLOG(2) << "Ignoring data type request for sync startup: "
+ << syncer::ModelTypeToString(type);
+}
+
+void ProfileSyncService::StartUpSlowBackendComponents() {
+ // Don't start up multiple times.
+ if (backend_) {
+ DVLOG(1) << "Skipping bringing up backend host.";
+ return;
}
DCHECK(IsSyncEnabledAndLoggedIn());
@@ -539,7 +603,7 @@ void ProfileSyncService::StartUpSlowBackendComponents(
//
// TODO(akalin): Fix this horribly non-intuitive behavior (see
// http://crbug.com/140354).
- if (backend_.get()) {
+ if (backend_) {
backend_->UpdateRegisteredInvalidationIds(
invalidator_registrar_->GetAllRegisteredIds());
for (AckHandleReplayQueue::const_iterator it = ack_replay_queue_.begin();
@@ -562,7 +626,7 @@ void ProfileSyncService::UpdateRegisteredInvalidationIds(
// If |backend_| is NULL, its registered IDs will be updated when
// it's created and initialized.
- if (backend_.get()) {
+ if (backend_) {
backend_->UpdateRegisteredInvalidationIds(
invalidator_registrar_->GetAllRegisteredIds());
}
@@ -576,7 +640,7 @@ void ProfileSyncService::UnregisterInvalidationHandler(
void ProfileSyncService::AcknowledgeInvalidation(
const invalidation::ObjectId& id,
const syncer::AckHandle& ack_handle) {
- if (backend_.get()) {
+ if (backend_) {
backend_->AcknowledgeInvalidation(id, ack_handle);
} else {
// If |backend_| is NULL, save the acknowledgements to replay when
@@ -618,7 +682,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) {
// applying changes to the sync db that wouldn't get applied via
// ChangeProcessors, leading to back-from-the-dead bugs.
base::Time shutdown_start_time = base::Time::Now();
- if (backend_.get()) {
+ if (backend_) {
backend_->StopSyncingForShutdown();
}
@@ -627,7 +691,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) {
// change from a native model. In that case, it will get applied to the sync
// database (which doesn't get destroyed until we destroy the backend below)
// as an unsynced change. That will be persisted, and committed on restart.
- if (data_type_manager_.get()) {
+ if (data_type_manager_) {
if (data_type_manager_->state() != DataTypeManager::STOPPED) {
// When aborting as part of shutdown, we should expect an aborted sync
// configure result, else we'll dcheck when we try to read the sync error.
@@ -645,7 +709,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) {
// Move aside the backend so nobody else tries to use it while we are
// shutting it down.
scoped_ptr<SyncBackendHost> doomed_backend(backend_.release());
- if (doomed_backend.get()) {
+ if (doomed_backend) {
doomed_backend->Shutdown(sync_disabled);
doomed_backend.reset();
@@ -660,7 +724,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) {
is_auth_in_progress_ = false;
backend_initialized_ = false;
// NULL if we're called from Shutdown().
- if (invalidator_registrar_.get())
+ if (invalidator_registrar_)
UpdateInvalidatorRegistrarState();
cached_passphrase_.clear();
encryption_pending_ = false;
@@ -671,7 +735,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) {
if (last_auth_error_.state() != GoogleServiceAuthError::NONE)
UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone());
- if (sync_global_error_.get()) {
+ if (sync_global_error_) {
GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(
sync_global_error_.get());
RemoveObserver(sync_global_error_.get());
@@ -713,6 +777,8 @@ void ProfileSyncService::NotifyObservers() {
void ProfileSyncService::ClearStaleErrors() {
ClearUnrecoverableError();
last_actionable_error_ = SyncProtocolError();
+ // Clear the data type errors as well.
+ failed_datatypes_handler_.OnUserChoseDatatypes();
}
void ProfileSyncService::ClearUnrecoverableError() {
@@ -726,7 +792,7 @@ void ProfileSyncService::ClearUnrecoverableError() {
std::string ProfileSyncService::GetExperimentNameForDataType(
syncer::ModelType data_type) {
NOTREACHED();
- return "";
+ return std::string();
}
void ProfileSyncService::RegisterNewDataType(syncer::ModelType data_type) {
@@ -950,7 +1016,7 @@ void ProfileSyncService::OnExperimentsChanged(
// Only automatically turn on types if we have already finished set up.
// Otherwise, just leave the experimental types on by default.
- if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_.get()) {
+ if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_) {
DVLOG(1) << "Dynamically enabling new datatypes: "
<< syncer::ModelTypeSetToString(to_register);
OnMigrationNeededForTypes(to_register);
@@ -964,12 +1030,6 @@ void ProfileSyncService::OnExperimentsChanged(
true);
}
- if (experiments.full_history_sync) {
- about_flags::SetExperimentEnabled(g_browser_process->local_state(),
- syncer::kFullHistorySyncFlag,
- true);
- }
-
if (experiments.favicon_sync) {
about_flags::SetExperimentEnabled(g_browser_process->local_state(),
syncer::kFaviconSyncFlag,
@@ -1078,7 +1138,7 @@ void ProfileSyncService::OnPassphraseAccepted() {
// this time.
const syncer::ModelTypeSet types = GetPreferredDataTypes();
- if (data_type_manager_.get()) {
+ if (data_type_manager_) {
// Unblock the data type manager if necessary.
data_type_manager_->Configure(types,
syncer::CONFIGURE_REASON_RECONFIGURATION);
@@ -1097,6 +1157,15 @@ void ProfileSyncService::OnEncryptedTypesChanged(
<< " (encrypt everything is set to "
<< (encrypt_everything_ ? "true" : "false") << ")";
DCHECK(encrypted_types_.Has(syncer::PASSWORDS));
+
+ // If sessions are encrypted, full history sync is not possible, and
+ // delete directives are unnecessary.
+ if (GetPreferredDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES) &&
+ encrypted_types_.Has(syncer::SESSIONS)) {
+ DisableBrokenDatatype(syncer::HISTORY_DELETE_DIRECTIVES,
+ FROM_HERE,
+ "Delete directives not supported with encryption.");
+ }
}
void ProfileSyncService::OnEncryptionComplete() {
@@ -1269,7 +1338,7 @@ void ProfileSyncService::OnConfigureStart() {
std::string ProfileSyncService::QuerySyncStatusSummary() {
if (HasUnrecoverableError()) {
return "Unrecoverable error detected";
- } else if (!backend_.get()) {
+ } else if (!backend_) {
return "Syncing not enabled";
} else if (backend_.get() && !HasSyncSetupCompleted()) {
return "First time sync setup incomplete";
@@ -1394,7 +1463,7 @@ const browser_sync::user_selectable_type::UserSelectableSyncType
browser_sync::user_selectable_type::PROXY_TABS
};
- COMPILE_ASSERT(26 == syncer::MODEL_TYPE_COUNT, UpdateCustomConfigHistogram);
+ COMPILE_ASSERT(27 == syncer::MODEL_TYPE_COUNT, UpdateCustomConfigHistogram);
if (!sync_everything) {
const syncer::ModelTypeSet current_types = GetPreferredDataTypes();
@@ -1513,6 +1582,17 @@ SyncBackendHost* ProfileSyncService::GetBackendForTest() {
return backend_.get();
}
+void ProfileSyncService::ConfigurePriorityDataTypes() {
+ const syncer::ModelTypeSet priority_types =
+ Intersection(GetPreferredDataTypes(), syncer::PriorityUserTypes());
+ if (!priority_types.Empty()) {
+ const syncer::ConfigureReason reason = HasSyncSetupCompleted() ?
+ syncer::CONFIGURE_REASON_RECONFIGURATION :
+ syncer::CONFIGURE_REASON_NEW_CLIENT;
+ data_type_manager_->Configure(priority_types, reason);
+ }
+}
+
void ProfileSyncService::ConfigureDataTypeManager() {
// Don't configure datatypes if the setup UI is still on the screen - this
// is to help multi-screen setting UIs (like iOS) where they don't want to
@@ -1523,7 +1603,7 @@ void ProfileSyncService::ConfigureDataTypeManager() {
return;
bool restart = false;
- if (!data_type_manager_.get()) {
+ if (!data_type_manager_) {
restart = true;
data_type_manager_.reset(
factory_->CreateDataTypeManager(debug_info_listener_,
@@ -1541,6 +1621,9 @@ void ProfileSyncService::ConfigureDataTypeManager() {
base::Unretained(this))));
}
+ // This is probably where we want to trigger configuration of priority
+ // datatypes, but we need to resolve crbug.com/226195 first.
+
#if defined(OS_ANDROID)
if (GetPreferredDataTypes().Has(syncer::PASSWORDS) &&
!ShouldEnablePasswordSyncForAndroid()) {
@@ -1700,7 +1783,7 @@ Value* ProfileSyncService::GetTypeStatusMap() const {
void ProfileSyncService::ActivateDataType(
syncer::ModelType type, syncer::ModelSafeGroup group,
ChangeProcessor* change_processor) {
- if (!backend_.get()) {
+ if (!backend_) {
NOTREACHED();
return;
}
@@ -1709,7 +1792,7 @@ void ProfileSyncService::ActivateDataType(
}
void ProfileSyncService::DeactivateDataType(syncer::ModelType type) {
- if (!backend_.get())
+ if (!backend_)
return;
backend_->DeactivateDataType(type);
}
@@ -1872,12 +1955,19 @@ void ProfileSyncService::Observe(int type,
// Initialize the backend if sync is enabled. If the sync token was
// not loaded, GetCredentials() will generate invalid credentials to
// cause the backend to generate an auth error (crbug.com/121755).
- if (backend_.get())
+ if (backend_)
backend_->UpdateCredentials(GetCredentials());
else
TryStart();
break;
}
+ case chrome::NOTIFICATION_TOKENS_CLEARED: {
+ // GetCredentials() will generate invalid credentials to cause the backend
+ // to generate an auth error.
+ if (backend_)
+ backend_->UpdateCredentials(GetCredentials());
+ break;
+ }
case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
// Disable sync if the user is signed out.
DisableForUser();
@@ -1926,7 +2016,7 @@ bool ProfileSyncService::ShouldPushChanges() {
if (HasUnrecoverableError())
return false;
- if (!data_type_manager_.get())
+ if (!data_type_manager_)
return false;
return data_type_manager_->state() == DataTypeManager::CONFIGURED;
@@ -2002,7 +2092,7 @@ void ProfileSyncService::UpdateInvalidatorRegistrarState() {
void ProfileSyncService::ResetForTest() {
Profile* profile = profile_;
- SigninManager* signin = SigninManagerFactory::GetForProfile(profile);
+ SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile);
ProfileSyncService::StartBehavior behavior =
browser_defaults::kSyncAutoStarts ? ProfileSyncService::AUTO_START
: ProfileSyncService::MANUAL_START;