diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:20:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:28:57 +0000 |
commit | d17ea114e5ef69ad5d5d7413280a13e6428098aa (patch) | |
tree | 2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/components/browser_sync | |
parent | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff) | |
download | qtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz |
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/components/browser_sync')
13 files changed, 410 insertions, 874 deletions
diff --git a/chromium/components/browser_sync/BUILD.gn b/chromium/components/browser_sync/BUILD.gn index d8c3092bfd1..716f6762beb 100644 --- a/chromium/components/browser_sync/BUILD.gn +++ b/chromium/components/browser_sync/BUILD.gn @@ -43,6 +43,7 @@ static_library("browser_sync") { "//components/version_info:generate_version_info", "//google_apis", "//net", + "//services/identity/public/cpp", ] } @@ -126,6 +127,7 @@ static_library("test_support") { "//components/sync_sessions:test_support", "//google_apis", "//net:test_support", + "//services/identity/public/cpp", "//testing/gmock", ] } diff --git a/chromium/components/browser_sync/DEPS b/chromium/components/browser_sync/DEPS index 6b9d9d2d88f..3bbcc3d8893 100644 --- a/chromium/components/browser_sync/DEPS +++ b/chromium/components/browser_sync/DEPS @@ -23,4 +23,5 @@ include_rules = [ "+components/webdata_services", "+google_apis", "+net", + "+services/identity/public/cpp", ] diff --git a/chromium/components/browser_sync/abstract_profile_sync_service_test.cc b/chromium/components/browser_sync/abstract_profile_sync_service_test.cc index cb706fa491b..a331fb14181 100644 --- a/chromium/components/browser_sync/abstract_profile_sync_service_test.cc +++ b/chromium/components/browser_sync/abstract_profile_sync_service_test.cc @@ -43,7 +43,7 @@ class SyncEngineForProfileSyncTest : public SyncBackendHostImpl { syncer::SyncClient* sync_client, invalidation::InvalidationService* invalidator, const base::WeakPtr<syncer::SyncPrefs>& sync_prefs, - const base::Closure& callback); + base::OnceClosure callback); ~SyncEngineForProfileSyncTest() override; void Initialize(InitParams params) override; @@ -54,7 +54,7 @@ class SyncEngineForProfileSyncTest : public SyncBackendHostImpl { // Invoked at the start of HandleSyncManagerInitializationOnFrontendLoop. // Allows extra initialization work to be performed before the engine comes // up. - base::Closure callback_; + base::OnceClosure callback_; DISALLOW_COPY_AND_ASSIGN(SyncEngineForProfileSyncTest); }; @@ -64,21 +64,22 @@ SyncEngineForProfileSyncTest::SyncEngineForProfileSyncTest( syncer::SyncClient* sync_client, invalidation::InvalidationService* invalidator, const base::WeakPtr<syncer::SyncPrefs>& sync_prefs, - const base::Closure& callback) + base::OnceClosure callback) : SyncBackendHostImpl( "dummy_debug_name", sync_client, invalidator, sync_prefs, temp_dir.Append(base::FilePath(FILE_PATH_LITERAL("test")))), - callback_(callback) {} + callback_(std::move(callback)) {} SyncEngineForProfileSyncTest::~SyncEngineForProfileSyncTest() {} void SyncEngineForProfileSyncTest::Initialize(InitParams params) { params.http_factory_getter = base::Bind(&GetHttpPostProviderFactory); params.sync_manager_factory = - std::make_unique<syncer::SyncManagerFactoryForProfileSyncTest>(callback_); + std::make_unique<syncer::SyncManagerFactoryForProfileSyncTest>( + std::move(callback_)); params.credentials.email = "testuser@gmail.com"; params.credentials.sync_token = "token"; params.credentials.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope); @@ -160,7 +161,7 @@ bool AbstractProfileSyncServiceTest::CreateRoot(ModelType model_type) { void AbstractProfileSyncServiceTest::CreateSyncService( std::unique_ptr<syncer::SyncClient> sync_client, - const base::Closure& initialization_success_callback) { + base::OnceClosure initialization_success_callback) { ASSERT_TRUE(sync_client); ProfileSyncService::InitParams init_params = profile_sync_service_bundle_.CreateBasicInitParams( @@ -175,7 +176,7 @@ void AbstractProfileSyncServiceTest::CreateSyncService( temp_dir_.GetPath(), sync_service_->GetSyncClient(), profile_sync_service_bundle_.fake_invalidation_service(), sync_service_->sync_prefs()->AsWeakPtr(), - initialization_success_callback))); + std::move(initialization_success_callback)))); sync_service_->SetFirstSetupComplete(); } diff --git a/chromium/components/browser_sync/abstract_profile_sync_service_test.h b/chromium/components/browser_sync/abstract_profile_sync_service_test.h index 2171b687c18..05d355b3d8e 100644 --- a/chromium/components/browser_sync/abstract_profile_sync_service_test.h +++ b/chromium/components/browser_sync/abstract_profile_sync_service_test.h @@ -53,7 +53,7 @@ class AbstractProfileSyncServiceTest : public testing::Test { // NotifyInitializationSuccess. |sync_client| is passed to the service. The // created service is stored in |sync_service_|. void CreateSyncService(std::unique_ptr<syncer::SyncClient> sync_client, - const base::Closure& initialization_success_callback); + base::OnceClosure initialization_success_callback); base::Thread* data_type_thread() { return &data_type_thread_; } diff --git a/chromium/components/browser_sync/profile_sync_components_factory_impl.cc b/chromium/components/browser_sync/profile_sync_components_factory_impl.cc index ac89e31d6ad..8eb5fb2810f 100644 --- a/chromium/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/chromium/components/browser_sync/profile_sync_components_factory_impl.cc @@ -16,8 +16,6 @@ #include "components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/browser/webdata/web_data_model_type_controller.h" -#include "components/autofill/core/common/autofill_pref_names.h" -#include "components/autofill/core/common/autofill_switches.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/browser_sync/profile_sync_service.h" #include "components/dom_distiller/core/dom_distiller_features.h" @@ -42,9 +40,6 @@ #include "components/sync_bookmarks/bookmark_model_associator.h" #include "components/sync_bookmarks/bookmark_model_type_controller.h" #include "components/sync_sessions/session_data_type_controller.h" -#include "google_apis/gaia/oauth2_token_service.h" -#include "google_apis/gaia/oauth2_token_service_request.h" -#include "net/url_request/url_request_context_getter.h" using base::FeatureList; using bookmarks::BookmarkModel; @@ -74,11 +69,6 @@ syncer::ModelTypeSet GetDisabledTypesFromCommandLine( return disabled_types; } -syncer::ModelTypeSet GetEnabledTypesFromCommandLine( - const base::CommandLine& command_line) { - return syncer::ModelTypeSet(); -} - } // namespace ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl( @@ -88,11 +78,8 @@ ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl( bool is_tablet, const base::CommandLine& command_line, const char* history_disabled_pref, - const GURL& sync_service_url, const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - OAuth2TokenService* token_service, - net::URLRequestContextGetter* url_request_context_getter, const scoped_refptr<autofill::AutofillWebDataService>& web_data_service, const scoped_refptr<password_manager::PasswordStore>& password_store) : sync_client_(sync_client), @@ -101,17 +88,10 @@ ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl( is_tablet_(is_tablet), command_line_(command_line), history_disabled_pref_(history_disabled_pref), - sync_service_url_(sync_service_url), ui_thread_(ui_thread), db_thread_(db_thread), - token_service_(token_service), - url_request_context_getter_(url_request_context_getter), web_data_service_(web_data_service), - password_store_(password_store), - weak_factory_(this) { - DCHECK(token_service_); - DCHECK(url_request_context_getter_); -} + password_store_(password_store) {} ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {} @@ -120,18 +100,17 @@ void ProfileSyncComponentsFactoryImpl::RegisterDataTypes( const RegisterDataTypesMethod& register_platform_types_method) { syncer::ModelTypeSet disabled_types = GetDisabledTypesFromCommandLine(command_line_); - syncer::ModelTypeSet enabled_types = - GetEnabledTypesFromCommandLine(command_line_); - RegisterCommonDataTypes(sync_service, disabled_types, enabled_types); - if (!register_platform_types_method.is_null()) + RegisterCommonDataTypes(sync_service, disabled_types); + if (!register_platform_types_method.is_null()) { + syncer::ModelTypeSet enabled_types; register_platform_types_method.Run(sync_service, disabled_types, enabled_types); + } } void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes( syncer::SyncService* sync_service, - syncer::ModelTypeSet disabled_types, - syncer::ModelTypeSet enabled_types) { + syncer::ModelTypeSet disabled_types) { base::Closure error_callback = base::Bind(&syncer::ReportUnrecoverableError, channel_); @@ -331,41 +310,6 @@ ProfileSyncComponentsFactoryImpl::CreateLocalDeviceInfoProvider() { channel_, version_, is_tablet_); } -class TokenServiceProvider - : public OAuth2TokenServiceRequest::TokenServiceProvider { - public: - TokenServiceProvider( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - OAuth2TokenService* token_service); - - // OAuth2TokenServiceRequest::TokenServiceProvider implementation. - scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner() - override; - OAuth2TokenService* GetTokenService() override; - - private: - ~TokenServiceProvider() override; - - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - OAuth2TokenService* token_service_; -}; - -TokenServiceProvider::TokenServiceProvider( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - OAuth2TokenService* token_service) - : task_runner_(task_runner), token_service_(token_service) {} - -TokenServiceProvider::~TokenServiceProvider() {} - -scoped_refptr<base::SingleThreadTaskRunner> -TokenServiceProvider::GetTokenServiceTaskRunner() { - return task_runner_; -} - -OAuth2TokenService* TokenServiceProvider::GetTokenService() { - return token_service_; -} - syncer::SyncApiComponentFactory::SyncComponents ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents( syncer::SyncService* sync_service, diff --git a/chromium/components/browser_sync/profile_sync_components_factory_impl.h b/chromium/components/browser_sync/profile_sync_components_factory_impl.h index fa0259a4b31..d72ed962a82 100644 --- a/chromium/components/browser_sync/profile_sync_components_factory_impl.h +++ b/chromium/components/browser_sync/profile_sync_components_factory_impl.h @@ -15,9 +15,6 @@ #include "components/sync/base/model_type.h" #include "components/sync/driver/sync_api_component_factory.h" #include "components/version_info/version_info.h" -#include "url/gurl.h" - -class OAuth2TokenService; namespace autofill { class AutofillWebDataService; @@ -27,23 +24,11 @@ namespace password_manager { class PasswordStore; } -namespace net { -class URLRequestContextGetter; -} - namespace browser_sync { class ProfileSyncComponentsFactoryImpl : public syncer::SyncApiComponentFactory { public: - // Constructs a ProfileSyncComponentsFactoryImpl. - // - // |sync_service_url| is the base URL of the sync server. - // - // |token_service| must outlive the ProfileSyncComponentsFactoryImpl. - // - // |url_request_context_getter| must outlive the - // ProfileSyncComponentsFactoryImpl. ProfileSyncComponentsFactoryImpl( syncer::SyncClient* sync_client, version_info::Channel channel, @@ -51,11 +36,8 @@ class ProfileSyncComponentsFactoryImpl bool is_tablet, const base::CommandLine& command_line, const char* history_disabled_pref, - const GURL& sync_service_url, const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - OAuth2TokenService* token_service, - net::URLRequestContextGetter* url_request_context_getter, const scoped_refptr<autofill::AutofillWebDataService>& web_data_service, const scoped_refptr<password_manager::PasswordStore>& password_store); ~ProfileSyncComponentsFactoryImpl() override; @@ -89,15 +71,10 @@ class ProfileSyncComponentsFactoryImpl private: // Register data types which are enabled on both desktop and mobile. - // |disabled_types| and |enabled_types| correspond only to those types - // being explicitly enabled/disabled by the command line. + // |disabled_types| corresponds only to those types being explicitly disabled + // by the command line. void RegisterCommonDataTypes(syncer::SyncService* sync_service, - syncer::ModelTypeSet disabled_types, - syncer::ModelTypeSet enabled_types); - - void DisableBrokenType(syncer::ModelType type, - const base::Location& from_here, - const std::string& message); + syncer::ModelTypeSet disabled_types); // Client/platform specific members. syncer::SyncClient* const sync_client_; @@ -106,16 +83,11 @@ class ProfileSyncComponentsFactoryImpl const bool is_tablet_; const base::CommandLine command_line_; const char* history_disabled_pref_; - const GURL sync_service_url_; const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; const scoped_refptr<base::SingleThreadTaskRunner> db_thread_; - OAuth2TokenService* const token_service_; - net::URLRequestContextGetter* const url_request_context_getter_; const scoped_refptr<autofill::AutofillWebDataService> web_data_service_; const scoped_refptr<password_manager::PasswordStore> password_store_; - base::WeakPtrFactory<ProfileSyncComponentsFactoryImpl> weak_factory_; - // Whether to override PREFERENCES to use USS. static bool override_prefs_controller_to_uss_for_test_; diff --git a/chromium/components/browser_sync/profile_sync_service.cc b/chromium/components/browser_sync/profile_sync_service.cc index 4d99038c24c..edb33dafe55 100644 --- a/chromium/components/browser_sync/profile_sync_service.cc +++ b/chromium/components/browser_sync/profile_sync_service.cc @@ -4,10 +4,7 @@ #include "components/browser_sync/profile_sync_service.h" -#include <stddef.h> - #include <cstddef> -#include <map> #include <utility> #include "base/bind.h" @@ -15,30 +12,23 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/feature_list.h" -#include "base/files/file_util.h" +#include "base/files/file_path.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/metrics/histogram.h" #include "base/metrics/histogram_macros.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" -#include "components/autofill/core/common/autofill_pref_names.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/invalidation/impl/invalidation_prefs.h" #include "components/invalidation/public/invalidation_service.h" #include "components/pref_registry/pref_registry_syncable.h" -#include "components/prefs/json_pref_store.h" #include "components/reading_list/features/reading_list_buildflags.h" -#include "components/signin/core/browser/about_signin_internals.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/sync/base/bind_to_task_runner.h" #include "components/sync/base/cryptographer.h" #include "components/sync/base/passphrase_type.h" -#include "components/sync/base/pref_names.h" #include "components/sync/base/report_unrecoverable_error.h" #include "components/sync/base/stop_source.h" #include "components/sync/base/system_encryptor.h" @@ -66,6 +56,7 @@ #include "components/sync/model/change_processor.h" #include "components/sync/model/model_type_change_processor.h" #include "components/sync/model/sync_error.h" +#include "components/sync/model_impl/client_tag_based_model_type_processor.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/syncable/directory.h" #include "components/sync/syncable/sync_db_util.h" @@ -86,6 +77,7 @@ using sync_sessions::SessionsSyncManager; using syncer::BackendMigrator; using syncer::ChangeProcessor; +using syncer::ClientTagBasedModelTypeProcessor; using syncer::DataTypeController; using syncer::DataTypeManager; using syncer::DataTypeStatusTable; @@ -109,8 +101,6 @@ namespace browser_sync { namespace { -using AuthError = GoogleServiceAuthError; - const char kSyncUnrecoverableErrorHistogram[] = "Sync.UnrecoverableErrors"; const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = { @@ -154,7 +144,9 @@ ProfileSyncService::ProfileSyncService(InitParams init_params) init_params.base_directory, init_params.debug_identifier), OAuth2TokenService::Consumer("sync"), - last_auth_error_(AuthError::AuthErrorNone()), + signin_scoped_device_id_callback_( + init_params.signin_scoped_device_id_callback), + last_auth_error_(GoogleServiceAuthError::AuthErrorNone()), sync_service_url_( syncer::GetSyncServiceURL(*base::CommandLine::ForCurrentProcess(), init_params.channel)), @@ -179,6 +171,7 @@ ProfileSyncService::ProfileSyncService(InitParams init_params) sync_enabled_weak_factory_(this), weak_factory_(this) { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(signin_scoped_device_id_callback_); DCHECK(sync_client_); std::string last_version = sync_prefs_.GetLastRunVersion(); std::string current_version = PRODUCT_VERSION; @@ -224,8 +217,6 @@ void ProfileSyncService::Initialize() { base::Bind(&ProfileSyncService::CanEngineStart, base::Unretained(this)), base::Bind(&ProfileSyncService::StartUpSlowEngineComponents, weak_factory_.GetWeakPtr())); - sync_sessions::LocalSessionEventRouter* router = - sync_client_->GetSyncSessionsClient()->GetLocalSessionEventRouter(); local_device_ = sync_client_->GetSyncApiComponentFactory() ->CreateLocalDeviceInfoProvider(); sync_stopped_reporter_ = std::make_unique<syncer::SyncStoppedReporter>( @@ -233,15 +224,15 @@ void ProfileSyncService::Initialize() { url_request_context_, syncer::SyncStoppedReporter::ResultCallback()); sessions_sync_manager_ = std::make_unique<SessionsSyncManager>( sync_client_->GetSyncSessionsClient(), &sync_prefs_, local_device_.get(), - router, base::Bind(&ProfileSyncService::NotifyForeignSessionUpdated, sync_enabled_weak_factory_.GetWeakPtr())); device_info_sync_bridge_ = std::make_unique<DeviceInfoSyncBridge>( local_device_.get(), model_type_store_factory_, - base::BindRepeating( - &ModelTypeChangeProcessor::Create, - base::BindRepeating(&syncer::ReportUnrecoverableError, channel_))); + std::make_unique<ClientTagBasedModelTypeProcessor>( + syncer::DEVICE_INFO, + /*dump_stack=*/base::BindRepeating(&syncer::ReportUnrecoverableError, + channel_))); syncer::SyncApiComponentFactory::RegisterDataTypesMethod register_platform_types_callback = @@ -346,14 +337,14 @@ void ProfileSyncService::StartSyncingWithServer() { void ProfileSyncService::RegisterAuthNotifications() { DCHECK(thread_checker_.CalledOnValidThread()); oauth2_token_service_->AddObserver(this); - if (signin()) - signin()->AddObserver(this); + if (signin_) + signin_->GetSigninManager()->AddObserver(this); } void ProfileSyncService::UnregisterAuthNotifications() { DCHECK(thread_checker_.CalledOnValidThread()); - if (signin()) - signin()->RemoveObserver(this); + if (signin_) + signin_->GetSigninManager()->RemoveObserver(this); if (oauth2_token_service_) oauth2_token_service_->RemoveObserver(this); } @@ -572,6 +563,8 @@ void ProfileSyncService::OnGetTokenSuccess( engine_->UpdateCredentials(GetCredentials()); else startup_controller_->TryStart(); + + UpdateAuthErrorState(GoogleServiceAuthError(GoogleServiceAuthError::NONE)); } void ProfileSyncService::OnGetTokenFailure( @@ -635,6 +628,31 @@ void ProfileSyncService::OnRefreshTokenRevoked(const std::string& account_id) { void ProfileSyncService::OnRefreshTokensLoaded() { DCHECK(thread_checker_.CalledOnValidThread()); + + GoogleServiceAuthError token_error = + oauth2_token_service_->GetAuthError(signin_->GetAccountIdToUse()); + if (token_error == GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( + GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_CLIENT)) { + // When the refresh token is replaced by a new token with a + // CREDENTIALS_REJECTED_BY_CLIENT error, Sync must be stopped immediately, + // even if the current access token is still valid. This happens e.g. when + // the user signs out of the web with Dice enabled. + // It is not necessary to do this when the refresh token is + // CREDENTIALS_REJECTED_BY_SERVER, because in that case the access token + // will be rejected by the server too. + // We only do this in OnRefreshTokensLoaded(), as opposed to + // OAuth2TokenService::Observer::OnAuthErrorChanged(), because + // CREDENTIALS_REJECTED_BY_CLIENT is only set by the signin component when + // the refresh token is created. + access_token_.clear(); + request_access_token_retry_timer_.Stop(); + access_token_request_.reset(); + is_auth_in_progress_ = false; + if (HasSyncingEngine()) + engine_->InvalidateCredentials(); + } + // This notification gets fired when OAuth2TokenService loads the tokens from // storage. Initialize the engine if sync is enabled. If the sync token was // not loaded, GetCredentials() will generate invalid credentials to cause the @@ -658,6 +676,8 @@ void ProfileSyncService::Shutdown() { sync_error_controller_.reset(); } + signin_scoped_device_id_callback_.Reset(); + if (sync_thread_) sync_thread_->Stop(); } @@ -897,17 +917,9 @@ void ProfileSyncService::OnEngineInitialized( sync_js_controller_.AttachJsBackend(js_backend); debug_info_listener_ = debug_info_listener; - std::string signin_scoped_device_id; - if (IsLocalSyncEnabled()) { - signin_scoped_device_id = "local_device"; - } else { - SigninClient* signin_client = signin_->GetOriginal()->signin_client(); - DCHECK(signin_client); - signin_scoped_device_id = signin_client->GetSigninScopedDeviceId(); - } - // Initialize local device info. - local_device_->Initialize(cache_guid, signin_scoped_device_id); + local_device_->Initialize(cache_guid, + signin_scoped_device_id_callback_.Run()); if (protocol_event_observers_.might_have_observers()) { engine_->RequestBufferedProtocolEventsAndEnableForwarding(); @@ -994,7 +1006,8 @@ void ProfileSyncService::OnExperimentsChanged( experiments.gcm_invalidations_enabled); } -void ProfileSyncService::UpdateAuthErrorState(const AuthError& error) { +void ProfileSyncService::UpdateAuthErrorState( + const GoogleServiceAuthError& error) { is_auth_in_progress_ = false; last_auth_error_ = error; @@ -1003,20 +1016,23 @@ void ProfileSyncService::UpdateAuthErrorState(const AuthError& error) { namespace { -AuthError ConnectionStatusToAuthError(syncer::ConnectionStatus status) { +GoogleServiceAuthError ConnectionStatusToAuthError( + syncer::ConnectionStatus status) { switch (status) { case syncer::CONNECTION_OK: - return AuthError::AuthErrorNone(); + return GoogleServiceAuthError::AuthErrorNone(); break; case syncer::CONNECTION_AUTH_ERROR: - return AuthError(AuthError::INVALID_GAIA_CREDENTIALS); + return GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( + GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_SERVER); break; case syncer::CONNECTION_SERVER_ERROR: - return AuthError(AuthError::CONNECTION_FAILED); + return GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED); break; default: NOTREACHED(); - return AuthError(AuthError::CONNECTION_FAILED); + return GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED); } } @@ -1062,6 +1078,9 @@ void ProfileSyncService::OnConnectionStatusChange( base::Bind(&ProfileSyncService::RequestAccessToken, sync_enabled_weak_factory_.GetWeakPtr())); } + // Make observers aware of the change. This call is unnecessary in the + // block below because UpdateAuthErrorState() will notify observers. + NotifyObservers(); } else { // Reset backoff time after successful connection. if (status == syncer::CONNECTION_OK) { @@ -1122,7 +1141,7 @@ void ProfileSyncService::OnActionableError(const SyncProtocolError& error) { // On every platform except ChromeOS, sign out the user after a dashboard // clear. if (!IsLocalSyncEnabled()) { - SigninManager::FromSigninManagerBase(signin_->GetOriginal()) + SigninManager::FromSigninManagerBase(signin_->GetSigninManager()) ->SignOut(signin_metrics::SERVER_FORCED_DISABLE, signin_metrics::SignoutDelete::IGNORE_METRIC); } @@ -1347,7 +1366,7 @@ bool ProfileSyncService::QueryDetailedSyncStatus(SyncEngine::Status* result) { return false; } -const AuthError& ProfileSyncService::GetAuthError() const { +const GoogleServiceAuthError& ProfileSyncService::GetAuthError() const { DCHECK(thread_checker_.CalledOnValidThread()); return last_auth_error_; } @@ -1530,6 +1549,20 @@ void ProfileSyncService::OnUserChoseDatatypes( ChangePreferredDataTypes(chosen_types); } +void ProfileSyncService::OnUserChangedSyncEverythingOnly(bool sync_everything) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (!engine_ && !HasUnrecoverableError()) { + NOTREACHED(); + return; + } + + sync_prefs_.SetKeepEverythingSynced(sync_everything); + UpdateSelectedTypesHistogram(sync_everything, GetPreferredDataTypes()); + if (data_type_manager_) + data_type_manager_->ResetDataTypeErrors(); + ReconfigureDatatypeManager(); +} + void ProfileSyncService::ChangePreferredDataTypes( syncer::ModelTypeSet preferred_types) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -1884,7 +1917,8 @@ void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) { void ProfileSyncService::GoogleSigninSucceeded(const std::string& account_id, const std::string& username) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!IsEngineInitialized() || GetAuthError().state() != AuthError::NONE) { + if (!IsEngineInitialized() || + GetAuthError().state() != GoogleServiceAuthError::NONE) { // Track the fact that we're still waiting for auth to complete. is_auth_in_progress_ = true; } @@ -2351,4 +2385,5 @@ void ProfileSyncService::OnSetupInProgressHandleDestroyed() { ReconfigureDatatypeManager(); NotifyObservers(); } + } // namespace browser_sync diff --git a/chromium/components/browser_sync/profile_sync_service.h b/chromium/components/browser_sync/profile_sync_service.h index 5a04d94f19a..7cc42542647 100644 --- a/chromium/components/browser_sync/profile_sync_service.h +++ b/chromium/components/browser_sync/profile_sync_service.h @@ -19,7 +19,6 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/observer_list.h" -#include "base/strings/string16.h" #include "base/threading/thread.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -130,6 +129,8 @@ namespace browser_sync { // // Sync configuration is accomplished via the following APIs: // * OnUserChoseDatatypes(): Set the data types the user wants to sync. +// * OnUserChangedSyncEverythingOnly(): Set only the keepEverythingSynced +// value. // * SetDecryptionPassphrase(): Attempt to decrypt the user's encrypted data // using the passed passphrase. // * SetEncryptionPassphrase(): Re-encrypt the user's data using the passed @@ -173,7 +174,8 @@ class ProfileSyncService : public syncer::SyncServiceBase, public GaiaCookieManagerService::Observer { public: using Status = syncer::SyncEngine::Status; - using PlatformSyncAllowedProvider = base::Callback<bool(void)>; + using PlatformSyncAllowedProvider = base::RepeatingCallback<bool()>; + using SigninScopedDeviceIdCallback = base::RepeatingCallback<std::string()>; enum SyncEventCodes { MIN_SYNC_EVENT_CODE = 0, @@ -228,6 +230,7 @@ class ProfileSyncService : public syncer::SyncServiceBase, std::unique_ptr<syncer::SyncClient> sync_client; std::unique_ptr<SigninManagerWrapper> signin_wrapper; + SigninScopedDeviceIdCallback signin_scoped_device_id_callback; ProfileOAuth2TokenService* oauth2_token_service = nullptr; GaiaCookieManagerService* gaia_cookie_manager_service = nullptr; StartBehavior start_behavior = MANUAL_START; @@ -314,6 +317,11 @@ class ProfileSyncService : public syncer::SyncServiceBase, callback) override; syncer::GlobalIdMapper* GetGlobalIdMapper() const override; + // Changes only the KeepEverythingSynced value. + // TODO(crbug/820625): Refactor sync code for more robust way to get/set + // preferred datatypes. + void OnUserChangedSyncEverythingOnly(bool sync_everything); + // Add a sync type preference provider. Each provider may only be added once. void AddPreferenceProvider(syncer::SyncTypePreferenceProvider* provider); // Remove a sync type preference provider. May only be called for providers @@ -739,6 +747,8 @@ class ProfileSyncService : public syncer::SyncServiceBase, // Called when a SetupInProgressHandle issued by this instance is destroyed. virtual void OnSetupInProgressHandleDestroyed(); + SigninScopedDeviceIdCallback signin_scoped_device_id_callback_; + // This is a cache of the last authentication response we received from the // sync server. The UI queries this to display appropriate messaging to the // user. diff --git a/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc b/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc index 54dd4a7ddfb..e5a17014324 100644 --- a/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc +++ b/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc @@ -29,10 +29,8 @@ #include "components/autofill/core/browser/country_names.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_change.h" #include "components/autofill/core/browser/webdata/autofill_data_type_controller.h" -#include "components/autofill/core/browser/webdata/autofill_entry.h" #include "components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h" #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_table.h" @@ -60,10 +58,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using autofill::AutocompleteSyncableService; using autofill::AutofillChange; using autofill::AutofillChangeList; -using autofill::AutofillEntry; using autofill::AutofillKey; using autofill::AutofillProfile; using autofill::AutofillProfileChange; @@ -77,7 +73,6 @@ using base::ASCIIToUTF16; using base::Time; using base::TimeDelta; using base::WaitableEvent; -using syncer::AUTOFILL; using syncer::AUTOFILL_PROFILE; using syncer::BaseNode; using syncer::syncable::CREATE; @@ -111,33 +106,11 @@ void RegisterAutofillPrefs(user_prefs::PrefRegistrySyncable* registry) { 0.0); } -void RunAndSignal(const base::Closure& cb, WaitableEvent* event) { - cb.Run(); +void RunAndSignal(base::OnceClosure cb, WaitableEvent* event) { + std::move(cb).Run(); event->Signal(); } -AutofillEntry MakeAutofillEntry(const std::string& name, - const std::string& value, - int time_shift0, - int time_shift1) { - // Time deep in the past would cause Autocomplete sync to discard the - // entries. - static Time base_time = Time::Now().LocalMidnight(); - - Time date_created = base_time + TimeDelta::FromSeconds(time_shift0); - Time date_last_used = date_created; - if (time_shift1 >= 0) - date_last_used = base_time + TimeDelta::FromSeconds(time_shift1); - return AutofillEntry(AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), - date_created, date_last_used); -} - -AutofillEntry MakeAutofillEntry(const std::string& name, - const std::string& value, - int time_shift) { - return MakeAutofillEntry(name, value, time_shift, -1); -} - } // namespace class AutofillTableMock : public AutofillTable { @@ -146,15 +119,11 @@ class AutofillTableMock : public AutofillTable { MOCK_METHOD2(RemoveFormElement, bool(const base::string16& name, const base::string16& value)); // NOLINT - MOCK_METHOD1(GetAllAutofillEntries, - bool(std::vector<AutofillEntry>* entries)); // NOLINT MOCK_METHOD4(GetAutofillTimestamps, bool(const base::string16& name, // NOLINT const base::string16& value, Time* date_created, Time* date_last_used)); - MOCK_METHOD1(UpdateAutofillEntries, - bool(const std::vector<AutofillEntry>&)); // NOLINT MOCK_METHOD1(GetAutofillProfiles, bool(std::vector<std::unique_ptr<AutofillProfile>>*)); // NOLINT MOCK_METHOD1(UpdateAutofillProfile, bool(const AutofillProfile&)); // NOLINT @@ -183,8 +152,8 @@ class MockAutofillBackend : public autofill::AutofillWebDataBackend { public: MockAutofillBackend( WebDatabase* web_database, - const base::Closure& on_changed, - const base::Callback<void(syncer::ModelType)>& on_sync_started, + const base::RepeatingClosure& on_changed, + const base::RepeatingCallback<void(syncer::ModelType)>& on_sync_started, const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) : web_database_(web_database), on_changed_(on_changed), @@ -212,28 +181,13 @@ class MockAutofillBackend : public autofill::AutofillWebDataBackend { private: WebDatabase* web_database_; - base::Closure on_changed_; - base::Callback<void(syncer::ModelType)> on_sync_started_; + base::RepeatingClosure on_changed_; + base::RepeatingCallback<void(syncer::ModelType)> on_sync_started_; const scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; }; class ProfileSyncServiceAutofillTest; -template <class AutofillProfile> -syncer::ModelType GetModelType() { - return syncer::UNSPECIFIED; -} - -template <> -syncer::ModelType GetModelType<AutofillEntry>() { - return AUTOFILL; -} - -template <> -syncer::ModelType GetModelType<AutofillProfile>() { - return AUTOFILL_PROFILE; -} - class TokenWebDataServiceFake : public TokenWebData { public: TokenWebDataServiceFake( @@ -268,7 +222,6 @@ class WebDataServiceFake : public AutofillWebDataService { const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner) : AutofillWebDataService(ui_task_runner, db_task_runner), web_database_(nullptr), - autocomplete_syncable_service_(nullptr), autofill_profile_syncable_service_(nullptr), syncable_service_created_or_destroyed_( base::WaitableEvent::ResetPolicy::AUTOMATIC, @@ -281,17 +234,17 @@ class WebDataServiceFake : public AutofillWebDataService { void StartSyncableService() { // The |autofill_profile_syncable_service_| must be constructed on the DB // sequence. - const base::Closure& on_changed_callback = base::Bind( + const base::RepeatingClosure& on_changed_callback = base::BindRepeating( &WebDataServiceFake::NotifyAutofillMultipleChangedOnUISequence, AsWeakPtr()); - const base::Callback<void(syncer::ModelType)> on_sync_started_callback = - base::Bind(&WebDataServiceFake::NotifySyncStartedOnUISequence, - AsWeakPtr()); + const base::RepeatingCallback<void(syncer::ModelType)>& + on_sync_started_callback = base::BindRepeating( + &WebDataServiceFake::NotifySyncStartedOnUISequence, AsWeakPtr()); db_task_runner_->PostTask( FROM_HERE, base::Bind(&WebDataServiceFake::CreateSyncableService, base::Unretained(this), on_changed_callback, - on_sync_started_callback)); + std::move(on_sync_started_callback))); syncable_service_created_or_destroyed_.Wait(); } @@ -308,27 +261,15 @@ class WebDataServiceFake : public AutofillWebDataService { WebDatabase* GetDatabase() override { return web_database_; } - void OnAutofillEntriesChanged(const AutofillChangeList& changes) { - WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - - base::Closure notify_cb = - base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged, - base::Unretained(autocomplete_syncable_service_), changes); - db_task_runner_->PostTask(FROM_HERE, - base::Bind(&RunAndSignal, notify_cb, &event)); - event.Wait(); - } - void OnAutofillProfileChanged(const AutofillProfileChange& changes) { WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); - base::Closure notify_cb = base::Bind( - &AutocompleteSyncableService::AutofillProfileChanged, + base::OnceClosure notify_cb = base::BindOnce( + &AutofillProfileSyncableService::AutofillProfileChanged, base::Unretained(autofill_profile_syncable_service_), changes); - db_task_runner_->PostTask(FROM_HERE, - base::Bind(&RunAndSignal, notify_cb, &event)); + db_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&RunAndSignal, std::move(notify_cb), &event)); event.Wait(); } @@ -336,20 +277,16 @@ class WebDataServiceFake : public AutofillWebDataService { ~WebDataServiceFake() override {} void CreateSyncableService( - const base::Closure& on_changed_callback, - const base::Callback<void(syncer::ModelType)>& on_sync_started) { + const base::RepeatingClosure& on_changed_callback, + const base::RepeatingCallback<void(syncer::ModelType)>& on_sync_started) { ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence()); // These services are deleted in DestroySyncableService(). backend_ = std::make_unique<MockAutofillBackend>( GetDatabase(), on_changed_callback, on_sync_started, ui_task_runner_.get()); - AutocompleteSyncableService::CreateForWebDataServiceAndBackend( - this, backend_.get()); AutofillProfileSyncableService::CreateForWebDataServiceAndBackend( this, backend_.get(), "en-US"); - autocomplete_syncable_service_ = - AutocompleteSyncableService::FromWebDataService(this); autofill_profile_syncable_service_ = AutofillProfileSyncableService::FromWebDataService(this); @@ -358,14 +295,12 @@ class WebDataServiceFake : public AutofillWebDataService { void DestroySyncableService() { ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence()); - autocomplete_syncable_service_ = nullptr; autofill_profile_syncable_service_ = nullptr; backend_.reset(); syncable_service_created_or_destroyed_.Signal(); } WebDatabase* web_database_; - AutocompleteSyncableService* autocomplete_syncable_service_; AutofillProfileSyncableService* autofill_profile_syncable_service_; std::unique_ptr<autofill::AutofillWebDataBackend> backend_; @@ -393,8 +328,7 @@ class MockPersonalDataManager : public PersonalDataManager { MOCK_METHOD0(Refresh, void()); }; -template <class T> -class AddAutofillHelper; +class AddAutofillProfileHelper; class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest, @@ -435,7 +369,8 @@ class ProfileSyncServiceAutofillTest personal_data_manager_->Init(web_data_service_, profile_sync_service_bundle()->pref_service(), - nullptr, false); + /*identity_manager=*/nullptr, + /*is_off_the_record=*/false); web_data_service_->StartSyncableService(); @@ -449,12 +384,6 @@ class ProfileSyncServiceAutofillTest builder.set_activate_model_creation(); sync_client_owned_ = builder.Build(); sync_client_ = sync_client_owned_.get(); - - // When UpdateAutofillEntries() is called with an empty list, the return - // value should be |true|, rather than the default of |false|. - std::vector<AutofillEntry> empty; - EXPECT_CALL(autofill_table_, UpdateAutofillEntries(empty)) - .WillRepeatedly(Return(true)); } ~ProfileSyncServiceAutofillTest() override { @@ -469,20 +398,18 @@ class ProfileSyncServiceAutofillTest sync_service()->Shutdown(); } - int GetSyncCount(syncer::ModelType type) { + int GetSyncCount() { syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); syncer::ReadNode node(&trans); - if (node.InitTypeRoot(type) != BaseNode::INIT_OK) + if (node.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) return 0; return node.GetTotalNodeCount() - 1; } - void StartSyncService(const base::Closure& callback, - bool will_fail_association, - syncer::ModelType type) { + void StartAutofillProfileSyncService(base::OnceClosure callback) { SigninManagerBase* signin = profile_sync_service_bundle()->signin_manager(); signin->SetAuthenticatedAccountInfo("12345", "test_user@gmail.com"); - CreateSyncService(std::move(sync_client_owned_), callback); + CreateSyncService(std::move(sync_client_owned_), std::move(callback)); EXPECT_CALL(*profile_sync_service_bundle()->component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) @@ -497,14 +424,17 @@ class ProfileSyncServiceAutofillTest profile_sync_service_bundle()->auth_service()->UpdateCredentials( signin->GetAuthenticatedAccountId(), "oauth2_login_token"); - sync_service()->RegisterDataTypeController(CreateDataTypeController(type)); + sync_service()->RegisterDataTypeController( + std::make_unique<AutofillProfileDataTypeController>( + data_type_thread()->task_runner(), base::DoNothing(), sync_client_, + web_data_service_)); sync_service()->Initialize(); base::RunLoop().Run(); // It's possible this test triggered an unrecoverable error, in which case // we can't get the sync count. if (sync_service()->IsSyncActive()) { - EXPECT_EQ(GetSyncCount(type), + EXPECT_EQ(GetSyncCount(), association_stats_.num_sync_items_after_association); } EXPECT_EQ(association_stats_.num_sync_items_after_association, @@ -513,23 +443,6 @@ class ProfileSyncServiceAutofillTest association_stats_.num_sync_items_deleted); } - bool AddAutofillSyncNode(const AutofillEntry& entry) { - syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare()); - syncer::WriteNode node(&trans); - std::string tag = AutocompleteSyncableService::KeyToTag( - base::UTF16ToUTF8(entry.key().name()), - base::UTF16ToUTF8(entry.key().value())); - syncer::WriteNode::InitUniqueByCreationResult result = - node.InitUniqueByCreation(AUTOFILL, tag); - if (result != syncer::WriteNode::INIT_SUCCESS) - return false; - - sync_pb::EntitySpecifics specifics; - AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics); - node.SetEntitySpecifics(specifics); - return true; - } - bool AddAutofillSyncNode(const AutofillProfile& profile) { syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare()); syncer::WriteNode node(&trans); @@ -545,45 +458,6 @@ class ProfileSyncServiceAutofillTest return true; } - bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries, - std::vector<AutofillProfile>* profiles) { - syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); - syncer::ReadNode autofill_root(&trans); - if (autofill_root.InitTypeRoot(AUTOFILL) != BaseNode::INIT_OK) { - return false; - } - - int64_t child_id = autofill_root.GetFirstChildId(); - while (child_id != syncer::kInvalidId) { - syncer::ReadNode child_node(&trans); - if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) - return false; - - const sync_pb::AutofillSpecifics& autofill( - child_node.GetEntitySpecifics().autofill()); - if (autofill.has_value()) { - AutofillKey key(base::UTF8ToUTF16(autofill.name()), - base::UTF8ToUTF16(autofill.value())); - std::vector<Time> timestamps; - int timestamps_count = autofill.usage_timestamp_size(); - for (int i = 0; i < timestamps_count; ++i) { - timestamps.push_back( - Time::FromInternalValue(autofill.usage_timestamp(i))); - } - entries->push_back( - AutofillEntry(key, timestamps.front(), timestamps.back())); - } else if (autofill.has_profile()) { - AutofillProfile p; - p.set_guid(autofill.profile().guid()); - AutofillProfileSyncableService::OverwriteProfileWithServerData( - autofill.profile(), &p); - profiles->push_back(p); - } - child_id = child_node.GetSuccessorId(); - } - return true; - } - bool GetAutofillProfilesFromSyncDBUnderProfileNode( std::vector<AutofillProfile>* profiles) { syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); @@ -613,24 +487,6 @@ class ProfileSyncServiceAutofillTest void SetIdleChangeProcessorExpectations() { EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0); EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0); - - // Only permit UpdateAutofillEntries() to be called with an empty list. - std::vector<AutofillEntry> empty; - EXPECT_CALL(autofill_table_, UpdateAutofillEntries(Not(empty))).Times(0); - } - - std::unique_ptr<syncer::DataTypeController> CreateDataTypeController( - syncer::ModelType type) { - DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE); - if (type == AUTOFILL) { - return std::make_unique<AutofillDataTypeController>( - data_type_thread()->task_runner(), base::DoNothing(), sync_client_, - web_data_service_); - } else { - return std::make_unique<AutofillProfileDataTypeController>( - data_type_thread()->task_runner(), base::DoNothing(), sync_client_, - web_data_service_); - } } AutofillTableMock& autofill_table() { return autofill_table_; } @@ -642,21 +498,14 @@ class ProfileSyncServiceAutofillTest WebDataServiceFake* web_data_service() { return web_data_service_.get(); } private: - friend class AddAutofillHelper<AutofillEntry>; - friend class AddAutofillHelper<AutofillProfile>; + friend class AddAutofillProfileHelper; base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( syncer::ModelType type) { - DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE); - if (type == AUTOFILL) { - return AutocompleteSyncableService::FromWebDataService( - web_data_service_.get()) - ->AsWeakPtr(); - } else { - return AutofillProfileSyncableService::FromWebDataService( - web_data_service_.get()) - ->AsWeakPtr(); - } + DCHECK(type == AUTOFILL_PROFILE); + return AutofillProfileSyncableService::FromWebDataService( + web_data_service_.get()) + ->AsWeakPtr(); } AutofillTableMock autofill_table_; @@ -675,24 +524,23 @@ class ProfileSyncServiceAutofillTest DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAutofillTest); }; -template <class T> -class AddAutofillHelper { +class AddAutofillProfileHelper { public: - AddAutofillHelper(ProfileSyncServiceAutofillTest* test, - const std::vector<T>& entries) - : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback, - base::Unretained(this), - test, - entries)), + AddAutofillProfileHelper(ProfileSyncServiceAutofillTest* test, + const std::vector<AutofillProfile>& entries) + : callback_(base::BindOnce(&AddAutofillProfileHelper::AddAutofillCallback, + base::Unretained(this), + test, + entries)), success_(false) {} - const base::Closure& callback() const { return callback_; } + base::OnceClosure callback() { return std::move(callback_); } bool success() { return success_; } private: void AddAutofillCallback(ProfileSyncServiceAutofillTest* test, - const std::vector<T>& entries) { - if (!test->CreateRoot(GetModelType<T>())) + const std::vector<AutofillProfile>& entries) { + if (!test->CreateRoot(AUTOFILL_PROFILE)) return; for (size_t i = 0; i < entries.size(); ++i) { @@ -702,167 +550,10 @@ class AddAutofillHelper { success_ = true; } - base::Closure callback_; + base::OnceClosure callback_; bool success_; }; -// Overload write transaction to use custom NotifyTransactionComplete -class WriteTransactionTest : public WriteTransaction { - public: - WriteTransactionTest(const base::Location& from_here, - WriterTag writer, - syncer::syncable::Directory* directory, - WaitableEvent* wait_for_syncapi) - : WriteTransaction(from_here, writer, directory), - wait_for_syncapi_(wait_for_syncapi) {} - - void NotifyTransactionComplete(syncer::ModelTypeSet types) override { - // This is where we differ. Force a thread change here, giving another - // thread a chance to create a WriteTransaction - wait_for_syncapi_->Wait(); - - WriteTransaction::NotifyTransactionComplete(types); - } - - private: - WaitableEvent* const wait_for_syncapi_; -}; - -// Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can -// post tasks with it. -class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> { - public: - FakeServerUpdater(TestProfileSyncService* service, - WaitableEvent* wait_for_start, - WaitableEvent* wait_for_syncapi, - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : entry_(MakeAutofillEntry("0", "0", 0)), - service_(service), - wait_for_start_(wait_for_start), - wait_for_syncapi_(wait_for_syncapi), - is_finished_(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED), - db_task_runner_(db_task_runner) {} - - void Update() { - // This gets called in a modelsafeworker thread. - ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence()); - - syncer::UserShare* user_share = service_->GetUserShare(); - syncer::syncable::Directory* directory = user_share->directory.get(); - - // Create autofill protobuf. - std::string tag = AutocompleteSyncableService::KeyToTag( - base::UTF16ToUTF8(entry_.key().name()), - base::UTF16ToUTF8(entry_.key().value())); - sync_pb::AutofillSpecifics new_autofill; - new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name())); - new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value())); - new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue()); - if (entry_.date_created() != entry_.date_last_used()) { - new_autofill.add_usage_timestamp( - entry_.date_last_used().ToInternalValue()); - } - - sync_pb::EntitySpecifics entity_specifics; - entity_specifics.mutable_autofill()->CopyFrom(new_autofill); - - { - // Tell main thread we've started - wait_for_start_->Signal(); - - // Create write transaction. - WriteTransactionTest trans(FROM_HERE, UNITTEST, directory, - wait_for_syncapi_); - - // Create actual entry based on autofill protobuf information. - // Simulates effects of UpdateLocalDataFromServerData - MutableEntry parent(&trans, GET_TYPE_ROOT, AUTOFILL); - MutableEntry item(&trans, CREATE, AUTOFILL, parent.GetId(), tag); - ASSERT_TRUE(item.good()); - item.PutSpecifics(entity_specifics); - item.PutServerSpecifics(entity_specifics); - item.PutBaseVersion(1); - syncer::syncable::Id server_item_id = - service_->id_factory()->NewServerId(); - item.PutId(server_item_id); - syncer::syncable::Id new_predecessor; - ASSERT_TRUE(item.PutPredecessor(new_predecessor)); - } - DVLOG(1) << "FakeServerUpdater finishing."; - is_finished_.Signal(); - } - - void CreateNewEntry(const AutofillEntry& entry) { - entry_ = entry; - ASSERT_FALSE(db_task_runner_->RunsTasksInCurrentSequence()); - if (!db_task_runner_->PostTask( - FROM_HERE, base::Bind(&FakeServerUpdater::Update, this))) { - NOTREACHED() << "Failed to post task to the db sequence."; - return; - } - } - - void WaitForUpdateCompletion() { is_finished_.Wait(); } - - private: - friend class base::RefCountedThreadSafe<FakeServerUpdater>; - ~FakeServerUpdater() {} - - AutofillEntry entry_; - TestProfileSyncService* service_; - WaitableEvent* const wait_for_start_; - WaitableEvent* const wait_for_syncapi_; - WaitableEvent is_finished_; - syncer::syncable::Id parent_id_; - scoped_refptr<base::SequencedTaskRunner> db_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(FakeServerUpdater); -}; - -// TODO(skrul): Test abort startup. -// TODO(skrul): Test processing of cloud changes. -// TODO(tim): Add autofill data type controller test, and a case to cover -// waiting for the PersonalDataManager. -TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) { - // Don't create the root autofill node so startup fails. - StartSyncService(base::Closure(), true, AUTOFILL); - EXPECT_TRUE(sync_service()->HasUnrecoverableError()); -} - -TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) { - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(Return(true)); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(create_root.callback(), false, AUTOFILL); - EXPECT_TRUE(create_root.success()); - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - EXPECT_EQ(0U, sync_entries.size()); - EXPECT_EQ(0U, sync_profiles.size()); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) { - std::vector<AutofillEntry> entries; - entries.push_back(MakeAutofillEntry("foo", "bar", 1)); - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true))); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - ASSERT_EQ(1U, sync_entries.size()); - EXPECT_EQ(entries[0], sync_entries[0]); - EXPECT_EQ(0U, sync_profiles.size()); -} - TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { std::vector<std::unique_ptr<AutofillProfile>> profiles; std::vector<AutofillProfile> expected_profiles; @@ -880,7 +571,7 @@ TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { EXPECT_CALL(personal_data_manager(), Refresh()); SetIdleChangeProcessorExpectations(); CreateRootHelper create_root(this, AUTOFILL_PROFILE); - StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(create_root.callback()); ASSERT_TRUE(create_root.success()); std::vector<AutofillProfile> sync_profiles; ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles)); @@ -888,140 +579,6 @@ TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0])); } -TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) { - // There is buggy autofill code that allows duplicate name/value - // pairs to exist in the database with separate pair_ids. - std::vector<AutofillEntry> entries; - entries.push_back(MakeAutofillEntry("foo", "bar", 1)); - entries.push_back(MakeAutofillEntry("dup", "", 2)); - entries.push_back(MakeAutofillEntry("dup", "", 3)); - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true))); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - EXPECT_EQ(2U, sync_entries.size()); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) { - AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1)); - AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2)); - - std::vector<AutofillEntry> native_entries; - native_entries.push_back(native_entry); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true))); - - std::vector<AutofillEntry> sync_entries; - sync_entries.push_back(sync_entry); - - AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); - - EXPECT_CALL(autofill_table(), UpdateAutofillEntries(ElementsAre(sync_entry))) - .WillOnce(Return(true)); - - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL); - ASSERT_TRUE(add_autofill.success()); - - std::set<AutofillEntry> expected_entries; - expected_entries.insert(native_entry); - expected_entries.insert(sync_entry); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), - new_sync_entries.end()); - - EXPECT_EQ(expected_entries, new_sync_entries_set); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge_NullTerminated) { - const char kEntry[] = "entry"; - // A value which contains null terminating symbol. - std::string entry(kEntry, arraysize(kEntry)); - AutofillEntry native_entry0(MakeAutofillEntry("native", kEntry, 1)); - AutofillEntry native_entry1(MakeAutofillEntry("native", entry, 1)); - AutofillEntry sync_entry0(MakeAutofillEntry("sync", kEntry, 2)); - AutofillEntry sync_entry1(MakeAutofillEntry("sync", entry, 2)); - - std::vector<AutofillEntry> native_entries; - native_entries.push_back(native_entry0); - native_entries.push_back(native_entry1); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true))); - - std::vector<AutofillEntry> sync_entries; - sync_entries.push_back(sync_entry0); - sync_entries.push_back(sync_entry1); - - AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); - - // Expecting that sync_entry0 and sync_entry1 will be written in an autofill - // table and a value in sync_entry1 won't lose null terminating symbol. - EXPECT_CALL(autofill_table(), - UpdateAutofillEntries(ElementsAre(sync_entry0, sync_entry1))) - .WillOnce(Return(true)); - - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL); - ASSERT_TRUE(add_autofill.success()); - - // Expecting that native_entry0 and native_entry1 won't merge into one entry. - std::set<AutofillEntry> expected_entries; - expected_entries.insert(native_entry0); - expected_entries.insert(native_entry1); - expected_entries.insert(sync_entry0); - expected_entries.insert(sync_entry1); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), - new_sync_entries.end()); - - EXPECT_EQ(expected_entries, new_sync_entries_set); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) { - AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1)); - AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2)); - AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2)); - - std::vector<AutofillEntry> native_entries; - native_entries.push_back(native_entry); - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true))); - - std::vector<AutofillEntry> sync_entries; - sync_entries.push_back(sync_entry); - AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); - - EXPECT_CALL(autofill_table(), - UpdateAutofillEntries(ElementsAre(merged_entry))) - .WillOnce(Return(true)); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL); - ASSERT_TRUE(add_autofill.success()); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(1U, new_sync_entries.size()); - EXPECT_EQ(merged_entry, new_sync_entries[0]); -} - TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) { AutofillProfile sync_profile; autofill::test::SetProfileInfoWithGuid( @@ -1046,13 +603,13 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) { std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(autofill_table(), UpdateAutofillProfile(MatchProfiles(sync_profile))) .WillOnce(Return(true)); EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1105,11 +662,11 @@ TEST_F( .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1170,11 +727,11 @@ TEST_F(ProfileSyncServiceAutofillTest, .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1237,11 +794,11 @@ TEST_F(ProfileSyncServiceAutofillTest, .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1289,11 +846,11 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSync_DifferentPrimaryInfo) { .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1336,13 +893,13 @@ TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) { std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(autofill_table(), AddAutofillProfile(_)).WillOnce(Return(true)); EXPECT_CALL(autofill_table(), RemoveAutofillProfile(native_guid)) .WillOnce(Return(true)); EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1359,41 +916,13 @@ TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) { EXPECT_EQ(base::Time::FromTimeT(1234), new_sync_profiles[0].use_date()); } -TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) { - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(Return(true)); - EXPECT_CALL(personal_data_manager(), Refresh()); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1)); - - EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _)) - .WillOnce(DoAll(SetArgPointee<2>(added_entry.date_created()), - SetArgPointee<3>(added_entry.date_last_used()), - Return(true))); - - AutofillChangeList changes; - changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key())); - - web_data_service()->OnAutofillEntriesChanged(changes); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(1U, new_sync_entries.size()); - EXPECT_EQ(added_entry, new_sync_entries[0]); -} TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).WillOnce(Return(true)); EXPECT_CALL(personal_data_manager(), Refresh()); SetIdleChangeProcessorExpectations(); CreateRootHelper create_root(this, AUTOFILL_PROFILE); - StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(create_root.callback()); ASSERT_TRUE(create_root.success()); AutofillProfile added_profile; @@ -1413,62 +942,6 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0])); } -TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) { - AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); - std::vector<AutofillEntry> original_entries; - original_entries.push_back(original_entry); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true))); - EXPECT_CALL(personal_data_manager(), Refresh()); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2)); - - EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _)) - .WillOnce(DoAll(SetArgPointee<2>(updated_entry.date_created()), - SetArgPointee<3>(updated_entry.date_last_used()), - Return(true))); - - AutofillChangeList changes; - changes.push_back( - AutofillChange(AutofillChange::UPDATE, updated_entry.key())); - web_data_service()->OnAutofillEntriesChanged(changes); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(1U, new_sync_entries.size()); - EXPECT_EQ(updated_entry, new_sync_entries[0]); -} - -TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) { - AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); - std::vector<AutofillEntry> original_entries; - original_entries.push_back(original_entry); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true))); - EXPECT_CALL(personal_data_manager(), Refresh()); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - AutofillChangeList changes; - changes.push_back( - AutofillChange(AutofillChange::REMOVE, original_entry.key())); - web_data_service()->OnAutofillEntriesChanged(changes); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(0U, new_sync_entries.size()); -} - TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { AutofillProfile sync_profile; autofill::test::SetProfileInfoWithGuid( @@ -1492,9 +965,9 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); AutofillProfileChange change(AutofillProfileChange::REMOVE, @@ -1507,62 +980,4 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { ASSERT_EQ(0U, new_sync_profiles.size()); } -TEST_F(ProfileSyncServiceAutofillTest, ServerChangeRace) { - // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via - // LoadAutofillData(). - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .Times(3) - .WillRepeatedly(Return(true)); - // On the other hand Autofill and Autocomplete are separated now, so - // GetAutofillProfiles() should not be called. - EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).Times(0); - EXPECT_CALL(autofill_table(), UpdateAutofillEntries(_)) - .WillRepeatedly(Return(true)); - EXPECT_CALL(personal_data_manager(), Refresh()).Times(3); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - std::unique_ptr<WaitableEvent> wait_for_start( - new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED)); - std::unique_ptr<WaitableEvent> wait_for_syncapi( - new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED)); - scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater( - sync_service(), wait_for_start.get(), wait_for_syncapi.get(), - data_type_thread()->task_runner())); - - // This server side update will stall waiting for CommitWaiter. - updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1)); - wait_for_start->Wait(); - - AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2)); - ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry)); - DVLOG(1) << "Syncapi update finished."; - - // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay! - // Signal FakeServerUpdater that it can complete. - wait_for_syncapi->Signal(); - - // Make another entry to ensure nothing broke afterwards and wait for finish - // to clean up. - updater->WaitForUpdateCompletion(); - updater->CreateNewEntry(MakeAutofillEntry("server2", "entry2", 3)); - updater->WaitForUpdateCompletion(); - - // Let callbacks posted on UI sequence execute. - base::RunLoop().RunUntilIdle(); - - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - EXPECT_EQ(3U, sync_entries.size()); - EXPECT_EQ(0U, sync_profiles.size()); - for (size_t i = 0; i < sync_entries.size(); i++) { - DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name() << ", " - << sync_entries[i].key().value(); - } -} - } // namespace browser_sync diff --git a/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc b/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc index e6695834cbd..722e16bc617 100644 --- a/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc +++ b/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc @@ -97,11 +97,6 @@ class ProfileSyncServiceStartupTest : public testing::Test { sync_service_->AddObserver(&observer_); } - void IssueTestTokens(const std::string& account_id) { - profile_sync_service_bundle_.auth_service()->UpdateCredentials( - account_id, "oauth2_login_token"); - } - void SetError(DataTypeManager::ConfigureResult* result) { syncer::DataTypeStatusTable::TypeErrorMap errors; errors[syncer::BOOKMARKS] = @@ -111,7 +106,7 @@ class ProfileSyncServiceStartupTest : public testing::Test { } protected: - std::string SimulateTestUserSignin(ProfileSyncService* sync_service) { + void SimulateTestUserSignin() { std::string account_id = profile_sync_service_bundle_.account_tracker()->SeedAccountInfo(kGaiaId, kEmail); @@ -121,12 +116,10 @@ class ProfileSyncServiceStartupTest : public testing::Test { profile_sync_service_bundle_.signin_manager()->SignIn(kGaiaId, kEmail, kDummyPassword); #else - profile_sync_service_bundle_.signin_manager()->SetAuthenticatedAccountInfo( - kGaiaId, kEmail); - if (sync_service) - sync_service->GoogleSigninSucceeded(account_id, kEmail); + profile_sync_service_bundle_.signin_manager()->SignIn(account_id); #endif - return account_id; + profile_sync_service_bundle_.auth_service()->UpdateCredentials( + account_id, "oauth2_login_token"); } DataTypeManagerMock* SetUpDataTypeManager() { @@ -159,7 +152,17 @@ class ProfileSyncServiceStartupCrosTest : public ProfileSyncServiceStartupTest { public: ProfileSyncServiceStartupCrosTest() { CreateSyncService(ProfileSyncService::AUTO_START); - SimulateTestUserSignin(nullptr); + // Set the primary account *without* providing an OAuth token. + std::string account_id = + profile_sync_service_bundle_.account_tracker()->SeedAccountInfo(kGaiaId, + kEmail); +#if !defined(OS_CHROMEOS) + const char kDummyPassword[] = "foobar"; + profile_sync_service_bundle_.signin_manager()->SignIn(kGaiaId, kEmail, + kDummyPassword); +#else + profile_sync_service_bundle_.signin_manager()->SignIn(account_id); +#endif EXPECT_TRUE( profile_sync_service_bundle_.signin_manager()->IsAuthenticated()); } @@ -198,10 +201,7 @@ TEST_F(ProfileSyncServiceStartupTest, StartFirstTime) { EXPECT_FALSE(sync_service_->IsSyncConfirmationNeeded()); // Simulate successful signin as test_user. - std::string account_id = SimulateTestUserSignin(sync_service_.get()); - ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); - // Create some tokens in the token service. - IssueTestTokens(account_id); + SimulateTestUserSignin(); // Simulate the UI telling sync it has finished setting up. sync_blocker.reset(); @@ -231,9 +231,7 @@ TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartNoCredentials) { auto sync_blocker = sync_service_->GetSetupInProgressHandle(); // Simulate successful signin as test_user. - std::string account_id = SimulateTestUserSignin(sync_service_.get()); - - profile_sync_service_bundle_.auth_service()->LoadCredentials(account_id); + SimulateTestUserSignin(); sync_blocker.reset(); // ProfileSyncService should try to start by requesting access token. @@ -246,7 +244,7 @@ TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartNoCredentials) { // TODO(pavely): Reenable test once android is switched to oauth2. TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartInvalidCredentials) { CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); FakeSyncEngine* mock_sbh = SetUpSyncEngine(); // Tell the backend to stall while downloading control types (simulating an @@ -270,7 +268,7 @@ TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartInvalidCredentials) { auto sync_blocker = sync_service_->GetSetupInProgressHandle(); // Simulate successful signin. - SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); sync_blocker.reset(); @@ -304,17 +302,14 @@ TEST_F(ProfileSyncServiceStartupCrosTest, StartFirstTime) { EXPECT_CALL(*data_type_manager, Stop()); EXPECT_CALL(observer_, OnStateChanged(_)).Times(AnyNumber()); - IssueTestTokens( - profile_sync_service_bundle_.account_tracker()->PickAccountIdForAccount( - "12345", kEmail)); + SimulateTestUserSignin(); sync_service_->Initialize(); EXPECT_TRUE(sync_service_->IsSyncActive()); } TEST_F(ProfileSyncServiceStartupTest, StartNormal) { - // Pre load the tokens CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); sync_service_->SetFirstSetupComplete(); SetUpSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); @@ -325,8 +320,6 @@ TEST_F(ProfileSyncServiceStartupTest, StartNormal) { EXPECT_CALL(observer_, OnStateChanged(_)).Times(AnyNumber()); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); - IssueTestTokens(account_id); - sync_service_->Initialize(); } @@ -343,9 +336,8 @@ TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) { syncer::SyncPrefs::GetPrefNameForDataType(iter.Get())); } - // Pre load the tokens CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); sync_service_->SetFirstSetupComplete(); SetUpSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); @@ -356,7 +348,6 @@ TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) { EXPECT_CALL(observer_, OnStateChanged(_)).Times(AnyNumber()); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); - IssueTestTokens(account_id); sync_service_->Initialize(); EXPECT_TRUE( @@ -370,9 +361,8 @@ TEST_F(ProfileSyncServiceStartupTest, StartDontRecoverDatatypePrefs) { // enabled. pref_service()->SetBoolean(syncer::prefs::kSyncKeepEverythingSynced, false); - // Pre load the tokens CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); sync_service_->SetFirstSetupComplete(); SetUpSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); @@ -382,7 +372,6 @@ TEST_F(ProfileSyncServiceStartupTest, StartDontRecoverDatatypePrefs) { EXPECT_CALL(*data_type_manager, Stop()).Times(1); EXPECT_CALL(observer_, OnStateChanged(_)).Times(AnyNumber()); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); - IssueTestTokens(account_id); sync_service_->Initialize(); EXPECT_FALSE( @@ -405,7 +394,7 @@ TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) { TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) { CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); sync_service_->SetFirstSetupComplete(); SetUpSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); @@ -414,7 +403,6 @@ TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) { .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); EXPECT_CALL(observer_, OnStateChanged(_)).Times(AnyNumber()); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); - IssueTestTokens(account_id); sync_service_->Initialize(); EXPECT_TRUE(sync_service_->IsEngineInitialized()); EXPECT_TRUE(sync_service_->IsSyncActive()); @@ -441,7 +429,7 @@ TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) { TEST_F(ProfileSyncServiceStartupTest, StartFailure) { CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); sync_service_->SetFirstSetupComplete(); SetUpSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); @@ -459,15 +447,13 @@ TEST_F(ProfileSyncServiceStartupTest, StartFailure) { .WillOnce(Return(DataTypeManager::STOPPED)); EXPECT_CALL(observer_, OnStateChanged(_)).Times(AnyNumber()); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); - IssueTestTokens(account_id); sync_service_->Initialize(); EXPECT_TRUE(sync_service_->HasUnrecoverableError()); } TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) { - // Pre load the tokens CreateSyncService(ProfileSyncService::MANUAL_START); - std::string account_id = SimulateTestUserSignin(sync_service_.get()); + SimulateTestUserSignin(); FakeSyncEngine* mock_sbh = SetUpSyncEngine(); mock_sbh->set_fail_initial_download(true); @@ -477,7 +463,6 @@ TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) { sync_service_->Initialize(); auto sync_blocker = sync_service_->GetSetupInProgressHandle(); - IssueTestTokens(account_id); sync_blocker.reset(); EXPECT_FALSE(sync_service_->IsSyncActive()); } diff --git a/chromium/components/browser_sync/profile_sync_service_unittest.cc b/chromium/components/browser_sync/profile_sync_service_unittest.cc index ffcb16bdb94..36e6591ae3a 100644 --- a/chromium/components/browser_sync/profile_sync_service_unittest.cc +++ b/chromium/components/browser_sync/profile_sync_service_unittest.cc @@ -88,16 +88,19 @@ using testing::_; class TestSyncServiceObserver : public syncer::SyncServiceObserver { public: - explicit TestSyncServiceObserver(ProfileSyncService* service) - : service_(service), setup_in_progress_(false) {} + TestSyncServiceObserver() + : setup_in_progress_(false), auth_error_(GoogleServiceAuthError()) {} void OnStateChanged(syncer::SyncService* sync) override { - setup_in_progress_ = service_->IsSetupInProgress(); + setup_in_progress_ = sync->IsSetupInProgress(); + auth_error_ = sync->GetAuthError(); } + bool setup_in_progress() const { return setup_in_progress_; } + GoogleServiceAuthError auth_error() const { return auth_error_; } private: - ProfileSyncService* service_; bool setup_in_progress_; + GoogleServiceAuthError auth_error_; }; // A variant of the FakeSyncEngine that won't automatically call back when asked @@ -139,6 +142,22 @@ class SyncEngineCaptureClearServerData : public FakeSyncEngine { ClearServerDataCalled clear_server_data_called_; }; +// FakeSyncEngine that calls an external callback when InvalidateCredentials is +// called. +class SyncEngineCaptureInvalidateCredentials : public FakeSyncEngine { + public: + explicit SyncEngineCaptureInvalidateCredentials( + const base::RepeatingClosure& invalidate_credentials_called) + : invalidate_credentials_called_(invalidate_credentials_called) {} + + void InvalidateCredentials() override { + invalidate_credentials_called_.Run(); + } + + private: + base::RepeatingClosure invalidate_credentials_called_; +}; + ACTION(ReturnNewFakeSyncEngine) { return new FakeSyncEngine(); } @@ -161,6 +180,10 @@ ACTION_P(ReturnNewMockHostCaptureClearServerData, captured_callback) { &OnClearServerDataCalled, base::Unretained(captured_callback))); } +ACTION_P(ReturnNewMockHostCaptureInvalidateCredentials, callback) { + return new SyncEngineCaptureInvalidateCredentials(callback); +} + // A test harness that uses a real ProfileSyncService and in most cases a // MockSyncEngine. // @@ -188,10 +211,14 @@ class ProfileSyncServiceTest : public ::testing::Test { std::string account_id = account_tracker()->SeedAccountInfo(kGaiaId, kEmail); auth_service()->UpdateCredentials(account_id, "oauth2_login_token"); +#if defined(OS_CHROMEOS) + signin_manager()->SignIn(account_id); +#else + signin_manager()->SignIn(kGaiaId, kEmail, "password"); +#endif } void CreateService(ProfileSyncService::StartBehavior behavior) { - signin_manager()->SetAuthenticatedAccountInfo(kGaiaId, kEmail); component_factory_ = profile_sync_service_bundle_.component_factory(); ProfileSyncServiceBundle::SyncClientBuilder builder( &profile_sync_service_bundle_); @@ -305,6 +332,13 @@ class ProfileSyncServiceTest : public ::testing::Test { .WillOnce(ReturnNewMockHostCaptureClearServerData(captured_callback)); } + void ExpectSyncEngineCreationCaptureInvalidateCredentials( + const base::RepeatingClosure& callback) { + EXPECT_CALL(*component_factory_, CreateSyncEngine(_, _, _, _)) + .Times(1) + .WillOnce(ReturnNewMockHostCaptureInvalidateCredentials(callback)); + } + void PrepareDelayedInitSyncEngine() { EXPECT_CALL(*component_factory_, CreateSyncEngine(_, _, _, _)) .WillOnce(ReturnNewSyncEngineNoReturn()); @@ -315,16 +349,16 @@ class ProfileSyncServiceTest : public ::testing::Test { } #if defined(OS_CHROMEOS) - SigninManagerBase* signin_manager() + FakeSigninManagerBase* signin_manager() #else - SigninManager* signin_manager() + FakeSigninManager* signin_manager() #endif // Opening brace is outside of macro to avoid confusing lint. { return profile_sync_service_bundle_.signin_manager(); } - ProfileOAuth2TokenService* auth_service() { + FakeProfileOAuth2TokenService* auth_service() { return profile_sync_service_bundle_.auth_service(); } @@ -419,7 +453,7 @@ TEST_F(ProfileSyncServiceTest, SetupInProgress) { CreateService(ProfileSyncService::AUTO_START); InitializeForFirstSync(); - TestSyncServiceObserver observer(service()); + TestSyncServiceObserver observer; service()->AddObserver(&observer); auto sync_blocker = service()->GetSetupInProgressHandle(); @@ -450,8 +484,8 @@ TEST_F(ProfileSyncServiceTest, DisabledByPolicyAfterInit) { ExpectSyncEngineCreation(1); InitializeForNthSync(); - EXPECT_FALSE(service()->IsManaged()); - EXPECT_TRUE(service()->IsSyncActive()); + ASSERT_FALSE(service()->IsManaged()); + ASSERT_TRUE(service()->IsSyncActive()); prefs()->SetManagedPref(syncer::prefs::kSyncManaged, std::make_unique<base::Value>(true)); @@ -468,7 +502,7 @@ TEST_F(ProfileSyncServiceTest, AbortedByShutdown) { IssueTestTokens(); InitializeForNthSync(); - EXPECT_FALSE(service()->IsSyncActive()); + ASSERT_FALSE(service()->IsSyncActive()); ShutdownAndDeleteService(); } @@ -502,8 +536,8 @@ TEST_F(ProfileSyncServiceTest, DisableAndEnableSyncTemporarily) { ExpectSyncEngineCreation(1); InitializeForNthSync(); - EXPECT_TRUE(service()->IsSyncActive()); - EXPECT_FALSE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart)); + ASSERT_TRUE(service()->IsSyncActive()); + ASSERT_FALSE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart)); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -548,10 +582,10 @@ TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { // Initial status. ProfileSyncService::SyncTokenStatus token_status = service()->GetSyncTokenStatus(); - EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); - EXPECT_TRUE(token_status.connection_status_update_time.is_null()); - EXPECT_TRUE(token_status.token_request_time.is_null()); - EXPECT_TRUE(token_status.token_receive_time.is_null()); + ASSERT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); + ASSERT_TRUE(token_status.connection_status_update_time.is_null()); + ASSERT_TRUE(token_status.token_request_time.is_null()); + ASSERT_TRUE(token_status.token_receive_time.is_null()); // Simulate an auth error. service()->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR); @@ -581,13 +615,13 @@ TEST_F(ProfileSyncServiceTest, RevokeAccessTokenFromTokenService) { ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback()); ExpectSyncEngineCreation(1); InitializeForNthSync(); - EXPECT_TRUE(service()->IsSyncActive()); + ASSERT_TRUE(service()->IsSyncActive()); std::string primary_account_id = signin_manager()->GetAuthenticatedAccountId(); auth_service()->LoadCredentials(primary_account_id); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(service()->GetAccessTokenForTest().empty()); + ASSERT_FALSE(service()->GetAccessTokenForTest().empty()); std::string secondary_account_gaiaid = "1234567"; std::string secondary_account_name = "test_user2@gmail.com"; @@ -602,6 +636,44 @@ TEST_F(ProfileSyncServiceTest, RevokeAccessTokenFromTokenService) { EXPECT_TRUE(service()->GetAccessTokenForTest().empty()); } +// Checks that CREDENTIALS_REJECTED_BY_CLIENT resets the access token and stops +// Sync. Regression test for https://crbug.com/824791. +TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient) { + bool invalidate_credentials_called = false; + base::RepeatingClosure invalidate_credentials_callback = + base::BindRepeating([](bool* called) { *called = true; }, + base::Unretained(&invalidate_credentials_called)); + CreateService(ProfileSyncService::AUTO_START); + IssueTestTokens(); + ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback()); + ExpectSyncEngineCreationCaptureInvalidateCredentials( + invalidate_credentials_callback); + InitializeForNthSync(); + ASSERT_TRUE(service()->IsSyncActive()); + + std::string primary_account_id = + signin_manager()->GetAuthenticatedAccountId(); + auth_service()->LoadCredentials(primary_account_id); + base::RunLoop().RunUntilIdle(); + ASSERT_FALSE(service()->GetAccessTokenForTest().empty()); + + GoogleServiceAuthError rejected_by_client = + GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( + GoogleServiceAuthError::InvalidGaiaCredentialsReason:: + CREDENTIALS_REJECTED_BY_CLIENT); + auth_service()->UpdateAuthErrorForTesting(primary_account_id, + rejected_by_client); + // The access token is not yet invalidated, it will be invalidated when + // OnRefreshTokenAvailable() is called. + EXPECT_FALSE(service()->GetAccessTokenForTest().empty()); + EXPECT_FALSE(invalidate_credentials_called); + auth_service()->LoadCredentials(primary_account_id); + ASSERT_EQ(rejected_by_client, + auth_service()->GetAuthError(primary_account_id)); + EXPECT_TRUE(service()->GetAccessTokenForTest().empty()); + EXPECT_TRUE(invalidate_credentials_called); +} + // CrOS does not support signout. #if !defined(OS_CHROMEOS) TEST_F(ProfileSyncServiceTest, SignOutRevokeAccessToken) { @@ -631,10 +703,10 @@ TEST_F(ProfileSyncServiceTest, ClearDataOnSignOut) { ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback()); ExpectSyncEngineCreation(1); InitializeForNthSync(); - EXPECT_TRUE(service()->IsSyncActive()); - EXPECT_LT(base::Time::Now() - service()->GetLastSyncedTime(), + ASSERT_TRUE(service()->IsSyncActive()); + ASSERT_LT(base::Time::Now() - service()->GetLastSyncedTime(), base::TimeDelta::FromMinutes(1)); - EXPECT_TRUE(service()->GetLocalDeviceInfoProvider()->GetLocalDeviceInfo()); + ASSERT_TRUE(service()->GetLocalDeviceInfoProvider()->GetLocalDeviceInfo()); // Sign out. service()->RequestStop(ProfileSyncService::CLEAR_DATA); @@ -644,6 +716,94 @@ TEST_F(ProfileSyncServiceTest, ClearDataOnSignOut) { EXPECT_FALSE(service()->GetLocalDeviceInfoProvider()->GetLocalDeviceInfo()); } +// Verify that credential errors get returned from GetAuthError(). +TEST_F(ProfileSyncServiceTest, CredentialErrorReturned) { + // This test needs to manually send access tokens (or errors), so disable + // automatic replies to access token requests. + auth_service()->set_auto_post_fetch_response_on_message_loop(false); + + CreateService(ProfileSyncService::AUTO_START); + IssueTestTokens(); + ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback()); + ExpectSyncEngineCreation(1); + InitializeForNthSync(); + ASSERT_TRUE(service()->IsSyncActive()); + + TestSyncServiceObserver observer; + service()->AddObserver(&observer); + + std::string primary_account_id = + signin_manager()->GetAuthenticatedAccountId(); + auth_service()->LoadCredentials(primary_account_id); + base::RunLoop().RunUntilIdle(); + auth_service()->IssueAllTokensForAccount(primary_account_id, "access token", + base::Time::Max()); + ASSERT_FALSE(service()->GetAccessTokenForTest().empty()); + ASSERT_EQ(GoogleServiceAuthError::NONE, service()->GetAuthError().state()); + + // Emulate Chrome receiving a new, invalid LST. This happens when the user + // signs out of the content area. + auth_service()->UpdateCredentials(primary_account_id, "not a valid token"); + auth_service()->IssueErrorForAllPendingRequests( + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + + // Check that the invalid token is returned from sync. + EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, + service()->GetAuthError().state()); + EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, + observer.auth_error().state()); + + service()->RemoveObserver(&observer); +} + +// Verify that credential errors get cleared when a new token is fetched +// successfully. +TEST_F(ProfileSyncServiceTest, CredentialErrorClearsOnNewToken) { + // This test needs to manually send access tokens (or errors), so disable + // automatic replies to access token requests. + auth_service()->set_auto_post_fetch_response_on_message_loop(false); + + CreateService(ProfileSyncService::AUTO_START); + IssueTestTokens(); + ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback()); + ExpectSyncEngineCreation(1); + InitializeForNthSync(); + ASSERT_TRUE(service()->IsSyncActive()); + + TestSyncServiceObserver observer; + service()->AddObserver(&observer); + + std::string primary_account_id = + signin_manager()->GetAuthenticatedAccountId(); + auth_service()->LoadCredentials(primary_account_id); + base::RunLoop().RunUntilIdle(); + auth_service()->IssueAllTokensForAccount(primary_account_id, "access token", + base::Time::Max()); + ASSERT_FALSE(service()->GetAccessTokenForTest().empty()); + ASSERT_EQ(GoogleServiceAuthError::NONE, service()->GetAuthError().state()); + + // Emulate Chrome receiving a new, invalid LST. This happens when the user + // signs out of the content area. + auth_service()->UpdateCredentials(primary_account_id, "not a valid token"); + auth_service()->IssueErrorForAllPendingRequests( + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + + // Check that the invalid token is returned from sync. + ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, + service()->GetAuthError().state()); + + // Now emulate Chrome receiving a new, valid LST. + auth_service()->UpdateCredentials(primary_account_id, "totally valid token"); + auth_service()->IssueTokenForAllPendingRequests( + "this one works", base::Time::Now() + base::TimeDelta::FromDays(10)); + + // Check that sync auth error state cleared. + EXPECT_EQ(GoogleServiceAuthError::NONE, service()->GetAuthError().state()); + EXPECT_EQ(GoogleServiceAuthError::NONE, observer.auth_error().state()); + + service()->RemoveObserver(&observer); +} + // Verify that the disable sync flag disables sync. TEST_F(ProfileSyncServiceTest, DisableSyncFlag) { base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync); @@ -663,16 +823,16 @@ TEST_F(ProfileSyncServiceTest, MemoryPressureRecording) { ExpectSyncEngineCreation(1); InitializeForNthSync(); - EXPECT_TRUE(service()->IsSyncActive()); - EXPECT_FALSE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart)); + ASSERT_TRUE(service()->IsSyncActive()); + ASSERT_FALSE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart)); testing::Mock::VerifyAndClearExpectations(component_factory()); syncer::SyncPrefs sync_prefs(service()->GetSyncClient()->GetPrefService()); - EXPECT_EQ(prefs()->GetInteger(syncer::prefs::kSyncMemoryPressureWarningCount), + ASSERT_EQ(prefs()->GetInteger(syncer::prefs::kSyncMemoryPressureWarningCount), 0); - EXPECT_FALSE(sync_prefs.DidSyncShutdownCleanly()); + ASSERT_FALSE(sync_prefs.DidSyncShutdownCleanly()); // Simulate memory pressure notification. base::MemoryPressureListener::NotifyMemoryPressure( @@ -715,9 +875,9 @@ TEST_F(ProfileSyncServiceTest, OnLocalSetPassphraseEncryption) { ExpectDataTypeManagerCreation( 1, GetRecordingConfigureCalledCallback(&configure_reason)); InitializeForNthSync(); - EXPECT_TRUE(service()->IsSyncActive()); + ASSERT_TRUE(service()->IsSyncActive()); testing::Mock::VerifyAndClearExpectations(component_factory()); - EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason); + ASSERT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason); syncer::DataTypeManager::ConfigureResult result; result.status = syncer::DataTypeManager::OK; service()->OnConfigureDone(result); @@ -764,7 +924,7 @@ TEST_F(ProfileSyncServiceTest, 1, GetRecordingConfigureCalledCallback(&configure_reason)); InitializeForNthSync(); testing::Mock::VerifyAndClearExpectations(component_factory()); - EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason); + ASSERT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason); syncer::DataTypeManager::ConfigureResult result; result.status = syncer::DataTypeManager::OK; service()->OnConfigureDone(result); @@ -777,12 +937,13 @@ TEST_F(ProfileSyncServiceTest, EXPECT_EQ(syncer::CONFIGURE_REASON_CATCH_UP, configure_reason); // Simulate browser restart. First configuration is a regular one. - service()->Shutdown(); + ShutdownAndDeleteService(); + CreateService(ProfileSyncService::AUTO_START); base::Closure captured_callback; ExpectSyncEngineCreationCaptureClearServerData(&captured_callback); ExpectDataTypeManagerCreation( 1, GetRecordingConfigureCalledCallback(&configure_reason)); - service()->RequestStart(); + InitializeForNthSync(); testing::Mock::VerifyAndClearExpectations(component_factory()); EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason); EXPECT_TRUE(captured_callback.is_null()); @@ -831,11 +992,12 @@ TEST_F(ProfileSyncServiceTest, captured_callback.Reset(); // Simulate browser restart. First configuration is a regular one. - service()->Shutdown(); + ShutdownAndDeleteService(); + CreateService(ProfileSyncService::AUTO_START); ExpectSyncEngineCreationCaptureClearServerData(&captured_callback); ExpectDataTypeManagerCreation( 1, GetRecordingConfigureCalledCallback(&configure_reason)); - service()->RequestStart(); + InitializeForNthSync(); testing::Mock::VerifyAndClearExpectations(component_factory()); EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason); EXPECT_TRUE(captured_callback.is_null()); @@ -872,7 +1034,7 @@ TEST_F(ProfileSyncServiceTest, PassphrasePromptDueToVersion) { InitializeForNthSync(); syncer::SyncPrefs sync_prefs(service()->GetSyncClient()->GetPrefService()); - EXPECT_EQ(PRODUCT_VERSION, sync_prefs.GetLastRunVersion()); + ASSERT_EQ(PRODUCT_VERSION, sync_prefs.GetLastRunVersion()); sync_prefs.SetPassphrasePrompted(true); @@ -918,10 +1080,10 @@ TEST_F(ProfileSyncServiceTest, DisableSyncOnClient) { ExpectSyncEngineCreation(1); InitializeForNthSync(); - EXPECT_TRUE(service()->IsSyncActive()); - EXPECT_LT(base::Time::Now() - service()->GetLastSyncedTime(), + ASSERT_TRUE(service()->IsSyncActive()); + ASSERT_LT(base::Time::Now() - service()->GetLastSyncedTime(), base::TimeDelta::FromMinutes(1)); - EXPECT_TRUE(service()->GetLocalDeviceInfoProvider()->GetLocalDeviceInfo()); + ASSERT_TRUE(service()->GetLocalDeviceInfoProvider()->GetLocalDeviceInfo()); syncer::SyncProtocolError client_cmd; client_cmd.action = syncer::DISABLE_SYNC_ON_CLIENT; diff --git a/chromium/components/browser_sync/profile_sync_test_util.cc b/chromium/components/browser_sync/profile_sync_test_util.cc index 249c55b7e3e..b2b6123a000 100644 --- a/chromium/components/browser_sync/profile_sync_test_util.cc +++ b/chromium/components/browser_sync/profile_sync_test_util.cc @@ -4,6 +4,7 @@ #include "components/browser_sync/profile_sync_test_util.h" +#include <string> #include <utility> #include "base/bind.h" @@ -232,6 +233,7 @@ ProfileSyncServiceBundle::ProfileSyncServiceBundle() &account_tracker_, nullptr), #endif + identity_manager_(&signin_manager_, &auth_service_), url_request_context_(new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())) { RegisterPrefsForProfileSyncService(pref_service_.registry()); @@ -249,11 +251,14 @@ ProfileSyncService::InitParams ProfileSyncServiceBundle::CreateBasicInitParams( init_params.start_behavior = start_behavior; init_params.sync_client = std::move(sync_client); - init_params.signin_wrapper = - std::make_unique<SigninManagerWrapper>(signin_manager()); + init_params.signin_wrapper = std::make_unique<SigninManagerWrapper>( + identity_manager(), signin_manager()); + init_params.signin_scoped_device_id_callback = + base::BindRepeating([]() { return std::string(); }); init_params.oauth2_token_service = auth_service(); init_params.network_time_update_callback = base::DoNothing(); - EXPECT_TRUE(base_directory_.CreateUniqueTempDir()); + if (!base_directory_.IsValid()) + EXPECT_TRUE(base_directory_.CreateUniqueTempDir()); init_params.base_directory = base_directory_.GetPath(); init_params.url_request_context = url_request_context(); init_params.debug_identifier = "dummyDebugName"; diff --git a/chromium/components/browser_sync/profile_sync_test_util.h b/chromium/components/browser_sync/profile_sync_test_util.h index 44eccf009f0..a576c343267 100644 --- a/chromium/components/browser_sync/profile_sync_test_util.h +++ b/chromium/components/browser_sync/profile_sync_test_util.h @@ -21,6 +21,7 @@ #include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/sync_sessions/mock_sync_sessions_client.h" +#include "services/identity/public/cpp/identity_manager.h" namespace history { class HistoryService; @@ -132,6 +133,8 @@ class ProfileSyncServiceBundle { FakeSigninManagerType* signin_manager() { return &signin_manager_; } + identity::IdentityManager* identity_manager() { return &identity_manager_; } + AccountTrackerService* account_tracker() { return &account_tracker_; } syncer::SyncApiComponentFactoryMock* component_factory() { @@ -160,6 +163,7 @@ class ProfileSyncServiceBundle { AccountTrackerService account_tracker_; FakeSigninManagerType signin_manager_; FakeProfileOAuth2TokenService auth_service_; + identity::IdentityManager identity_manager_; syncer::SyncApiComponentFactoryMock component_factory_; testing::NiceMock<sync_sessions::MockSyncSessionsClient> sync_sessions_client_; |