| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/callback_list.h" |
| #include "base/files/file_util.h" |
| #include "base/macros.h" |
| #include "base/path_service.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/defaults.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" |
| #include "chrome/browser/sync/test/integration/secondary_account_helper.h" |
| #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" |
| #include "chrome/browser/sync/test/integration/sync_test.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "components/sync/base/model_type.h" |
| #include "components/sync/driver/profile_sync_service.h" |
| #include "components/sync/driver/sync_driver_switches.h" |
| |
| namespace { |
| |
| #if !defined(OS_CHROMEOS) |
| syncer::ModelTypeSet AllowedTypesInStandaloneTransportMode() { |
| // Only some special whitelisted types (and control types) are allowed in |
| // standalone transport mode. |
| syncer::ModelTypeSet allowed_types(syncer::USER_CONSENTS, |
| syncer::SECURITY_EVENTS, |
| syncer::AUTOFILL_WALLET_DATA); |
| allowed_types.PutAll(syncer::ControlTypes()); |
| if (base::FeatureList::IsEnabled(switches::kSyncDeviceInfoInTransportMode)) { |
| allowed_types.Put(syncer::DEVICE_INFO); |
| } |
| return allowed_types; |
| } |
| |
| base::FilePath GetTestFilePathForCacheGuid() { |
| base::FilePath user_data_path; |
| base::PathService::Get(chrome::DIR_USER_DATA, &user_data_path); |
| return user_data_path.AppendASCII("SyncTestTmpCacheGuid"); |
| } |
| #endif // !defined(OS_CHROMEOS) |
| |
| class SingleClientSecondaryAccountSyncTest : public SyncTest { |
| public: |
| SingleClientSecondaryAccountSyncTest() : SyncTest(SINGLE_CLIENT) {} |
| ~SingleClientSecondaryAccountSyncTest() override {} |
| |
| void SetUpInProcessBrowserTestFixture() override { |
| test_signin_client_factory_ = |
| secondary_account_helper::SetUpSigninClient(&test_url_loader_factory_); |
| } |
| |
| void SetUpOnMainThread() override { |
| #if defined(OS_CHROMEOS) |
| secondary_account_helper::InitNetwork(); |
| #endif // defined(OS_CHROMEOS) |
| SyncTest::SetUpOnMainThread(); |
| } |
| |
| Profile* profile() { return GetProfile(0); } |
| |
| private: |
| base::test::ScopedFeatureList features_; |
| |
| secondary_account_helper::ScopedSigninClientFactory |
| test_signin_client_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SingleClientSecondaryAccountSyncTest); |
| }; |
| |
| // The unconsented primary account (aka secondary account) isn't supported on |
| // ChromeOS, see IdentityManager::ComputeUnconsentedPrimaryAccountInfo(). |
| #if !defined(OS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(SingleClientSecondaryAccountSyncTest, |
| StartsSyncTransportOnSignin) { |
| ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
| |
| // Signing in (without making the account Chrome's primary one or explicitly |
| // setting up Sync) should trigger starting the Sync machinery in standalone |
| // transport mode. |
| secondary_account_helper::SignInSecondaryAccount( |
| profile(), &test_url_loader_factory_, "user@email.com"); |
| EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING, |
| GetSyncService(0)->GetTransportState()); |
| |
| EXPECT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE, |
| GetSyncService(0)->GetTransportState()); |
| |
| ASSERT_EQ(browser_defaults::kSyncAutoStarts, |
| GetSyncService(0)->GetUserSettings()->IsFirstSetupComplete()); |
| |
| EXPECT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); |
| EXPECT_FALSE(GetSyncService(0)->IsSyncFeatureActive()); |
| |
| // Make sure that only the allowed types got activated. Note that, depending |
| // on some other feature flags, not all of the allowed types are necessarily |
| // active, and that's okay. |
| syncer::ModelTypeSet bad_types = |
| syncer::Difference(GetSyncService(0)->GetActiveDataTypes(), |
| AllowedTypesInStandaloneTransportMode()); |
| EXPECT_TRUE(bad_types.Empty()) << syncer::ModelTypeSetToString(bad_types); |
| } |
| #else |
| IN_PROC_BROWSER_TEST_F(SingleClientSecondaryAccountSyncTest, |
| DoesNotStartSyncTransportOnSignin) { |
| ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
| |
| // Signing in (without making the account Chrome's primary one or explicitly |
| // setting up Sync) should do nothing here, since we're on a platform where |
| // the unconsented primary account (aka secondary account) is not supported. |
| secondary_account_helper::SignInSecondaryAccount( |
| profile(), &test_url_loader_factory_, "user@email.com"); |
| EXPECT_EQ(syncer::SyncService::TransportState::DISABLED, |
| GetSyncService(0)->GetTransportState()); |
| } |
| #endif // !defined(OS_CHROMEOS) |
| |
| // ChromeOS doesn't support changes to the primary account after startup, so |
| // this test doesn't apply. |
| #if !defined(OS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(SingleClientSecondaryAccountSyncTest, |
| SwitchesFromTransportToFeature) { |
| ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
| |
| // Set up Sync in transport mode for a non-primary account. |
| secondary_account_helper::SignInSecondaryAccount( |
| profile(), &test_url_loader_factory_, "user@email.com"); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE, |
| GetSyncService(0)->GetTransportState()); |
| ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); |
| ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive()); |
| |
| // Simulate the user opting in to full Sync: Make the account primary, and |
| // set first-time setup to complete. |
| secondary_account_helper::MakeAccountPrimary(profile(), "user@email.com"); |
| GetSyncService(0)->GetUserSettings()->SetSyncRequested(true); |
| GetSyncService(0)->GetUserSettings()->SetFirstSetupComplete( |
| syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); |
| |
| EXPECT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); |
| EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE, |
| GetSyncService(0)->GetTransportState()); |
| EXPECT_TRUE(GetSyncService(0)->IsSyncFeatureEnabled()); |
| EXPECT_TRUE(GetSyncService(0)->IsSyncFeatureActive()); |
| |
| // Make sure that some model type which is not allowed in transport-only mode |
| // got activated. |
| ASSERT_FALSE(AllowedTypesInStandaloneTransportMode().Has(syncer::BOOKMARKS)); |
| ASSERT_TRUE(GetSyncService(0)->GetUserSettings()->GetSelectedTypes().Has( |
| syncer::UserSelectableType::kBookmarks)); |
| EXPECT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::BOOKMARKS)); |
| } |
| #endif // !defined(OS_CHROMEOS) |
| |
| // Regression test for crbug.com/955989 that verifies the cache GUID is not |
| // reset upon restart of the browser, in standalone transport mode with |
| // secondary accounts. |
| // |
| // The unconsented primary account (aka secondary account) isn't supported on |
| // ChromeOS, see IdentityManager::ComputeUnconsentedPrimaryAccountInfo(). |
| #if !defined(OS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(SingleClientSecondaryAccountSyncTest, |
| PRE_ReusesSameCacheGuid) { |
| ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
| secondary_account_helper::SignInSecondaryAccount( |
| profile(), &test_url_loader_factory_, "user@email.com"); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE, |
| GetSyncService(0)->GetTransportState()); |
| |
| ASSERT_FALSE(GetSyncService(0)->GetUserSettings()->IsFirstSetupComplete()); |
| ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); |
| |
| syncer::SyncPrefs prefs(GetProfile(0)->GetPrefs()); |
| const std::string cache_guid = prefs.GetCacheGuid(); |
| ASSERT_FALSE(cache_guid.empty()); |
| |
| // Save the cache GUID to file to remember after restart, for test |
| // verification purposes only. |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| ASSERT_NE(-1, base::WriteFile(GetTestFilePathForCacheGuid(), |
| cache_guid.c_str(), cache_guid.size())); |
| } |
| #endif // !defined(OS_CHROMEOS) |
| |
| // The unconsented primary account (aka secondary account) isn't supported on |
| // ChromeOS, see IdentityManager::ComputeUnconsentedPrimaryAccountInfo(). |
| #if !defined(OS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(SingleClientSecondaryAccountSyncTest, |
| ReusesSameCacheGuid) { |
| ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE, |
| GetSyncService(0)->GetTransportState()); |
| |
| ASSERT_FALSE(GetSyncService(0)->GetUserSettings()->IsFirstSetupComplete()); |
| ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); |
| |
| syncer::SyncPrefs prefs(GetProfile(0)->GetPrefs()); |
| ASSERT_FALSE(prefs.GetCacheGuid().empty()); |
| |
| std::string old_cache_guid; |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| ASSERT_TRUE( |
| base::ReadFileToString(GetTestFilePathForCacheGuid(), &old_cache_guid)); |
| ASSERT_FALSE(old_cache_guid.empty()); |
| |
| EXPECT_EQ(old_cache_guid, prefs.GetCacheGuid()); |
| } |
| #endif // !defined(OS_CHROMEOS) |
| |
| } // namespace |