// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/password_manager/android/password_manager_settings_service_android_impl.h"
#include <memory>
#include <optional>
#include "base/feature_list.h"
#include "base/memory/weak_ptr.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/password_manager/android/fake_password_manager_lifecycle_helper.h"
#include "chrome/browser/password_manager/android/password_settings_updater_android_bridge_helper.h"
#include "components/password_manager/core/browser/features/password_features.h"
#include "components/password_manager/core/browser/password_manager_setting.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/service/sync_user_settings.h"
#include "components/sync/test/test_sync_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
using password_manager::FakePasswordManagerLifecycleHelper;
using password_manager::PasswordManagerSetting;
using password_manager::PasswordSettingsUpdaterAndroidBridgeHelper;
using Consumer =
password_manager::PasswordSettingsUpdaterAndroidReceiverBridge::Consumer;
using SyncingAccount = password_manager::
PasswordSettingsUpdaterAndroidReceiverBridge::SyncingAccount;
using testing::_;
using testing::Eq;
const char kTestAccount[] = "[email protected]";
class MockPasswordSettingsUpdaterBridgeHelper
: public PasswordSettingsUpdaterAndroidBridgeHelper {
public:
MOCK_METHOD(void, SetConsumer, (base::WeakPtr<Consumer>), (override));
MOCK_METHOD(void,
GetPasswordSettingValue,
(std::optional<SyncingAccount>, PasswordManagerSetting),
(override));
MOCK_METHOD(void,
SetPasswordSettingValue,
(std::optional<SyncingAccount>, PasswordManagerSetting, bool),
(override));
};
} // namespace
class PasswordManagerSettingsServiceAndroidImplBaseTest : public testing::Test {
protected:
PasswordManagerSettingsServiceAndroidImplBaseTest();
~PasswordManagerSettingsServiceAndroidImplBaseTest() override;
void InitializeSettingsService(bool password_sync_enabled,
bool setting_sync_enabled);
std::unique_ptr<PasswordManagerSettingsServiceAndroidImpl> CreateNewService(
std::unique_ptr<MockPasswordSettingsUpdaterBridgeHelper> bridge_helper);
void SetPasswordsSync(bool enabled);
void SetSettingsSync(bool enabled);
void ExpectSettingsRetrievalFromBackend(std::optional<SyncingAccount> account,
size_t times);
void ExpectSettingsRetrievalFromBackend();
Consumer* updater_bridge_consumer() { return settings_service_.get(); }
password_manager::PasswordManagerSettingsService* settings_service() {
return settings_service_.get();
}
TestingPrefServiceSimple* pref_service() { return &test_pref_service_; }
syncer::TestSyncService* sync_service() { return &test_sync_service_; }
FakePasswordManagerLifecycleHelper* lifecycle_helper() {
return fake_lifecycle_helper_;
}
MockPasswordSettingsUpdaterBridgeHelper* bridge_helper() {
return mock_bridge_helper_;
}
base::HistogramTester* histogram_tester() { return &histogram_tester_; }
private:
void RegisterPrefs();
TestingPrefServiceSimple test_pref_service_;
std::unique_ptr<PasswordManagerSettingsServiceAndroidImpl> settings_service_;
syncer::TestSyncService test_sync_service_;
raw_ptr<MockPasswordSettingsUpdaterBridgeHelper> mock_bridge_helper_ =
nullptr;
raw_ptr<FakePasswordManagerLifecycleHelper> fake_lifecycle_helper_ = nullptr;
base::HistogramTester histogram_tester_;
};
PasswordManagerSettingsServiceAndroidImplBaseTest::
PasswordManagerSettingsServiceAndroidImplBaseTest() {
RegisterPrefs();
CoreAccountInfo sync_account_info;
sync_account_info.email = kTestAccount;
test_sync_service_.SetSignedIn(signin::ConsentLevel::kSync,
sync_account_info);
}
PasswordManagerSettingsServiceAndroidImplBaseTest::
~PasswordManagerSettingsServiceAndroidImplBaseTest() {
testing::Mock::VerifyAndClearExpectations(mock_bridge_helper_);
}
void PasswordManagerSettingsServiceAndroidImplBaseTest::
InitializeSettingsService(bool password_sync_enabled,
bool setting_sync_enabled) {
std::unique_ptr<MockPasswordSettingsUpdaterBridgeHelper> bridge_helper =
std::make_unique<MockPasswordSettingsUpdaterBridgeHelper>();
mock_bridge_helper_ = bridge_helper.get();
EXPECT_CALL(*mock_bridge_helper_, SetConsumer);
std::unique_ptr<FakePasswordManagerLifecycleHelper> lifecycle_helper =
std::make_unique<FakePasswordManagerLifecycleHelper>();
fake_lifecycle_helper_ = lifecycle_helper.get();
SetPasswordsSync(password_sync_enabled);
SetSettingsSync(setting_sync_enabled);
settings_service_ = std::make_unique<
PasswordManagerSettingsServiceAndroidImpl>(
base::PassKey<class PasswordManagerSettingsServiceAndroidImplBaseTest>(),
&test_pref_service_, &test_sync_service_, std::move(bridge_helper),
std::move(lifecycle_helper));
}
std::unique_ptr<PasswordManagerSettingsServiceAndroidImpl>
PasswordManagerSettingsServiceAndroidImplBaseTest::CreateNewService(
std::unique_ptr<MockPasswordSettingsUpdaterBridgeHelper> bridge_helper =
nullptr) {
if (!bridge_helper) {
bridge_helper = std::make_unique<MockPasswordSettingsUpdaterBridgeHelper>();
}
std::unique_ptr<FakePasswordManagerLifecycleHelper> lifecycle_helper =
std::make_unique<FakePasswordManagerLifecycleHelper>();
return std::make_unique<PasswordManagerSettingsServiceAndroidImpl>(
base::PassKey<class PasswordManagerSettingsServiceAndroidImplBaseTest>(),
pref_service(), sync_service(), std::move(bridge_helper),
std::move(lifecycle_helper));
}
void PasswordManagerSettingsServiceAndroidImplBaseTest::SetPasswordsSync(
bool enabled) {
syncer::UserSelectableTypeSet selected_sync_types =
test_sync_service_.GetUserSettings()->GetSelectedTypes();
if (enabled) {
selected_sync_types.Put(syncer::UserSelectableType::kPasswords);
} else {
selected_sync_types.Remove(syncer::UserSelectableType::kPasswords);
}
test_sync_service_.GetUserSettings()->SetSelectedTypes(false,
selected_sync_types);
}
void PasswordManagerSettingsServiceAndroidImplBaseTest::SetSettingsSync(
bool enabled) {
syncer::UserSelectableTypeSet selected_sync_types =
test_sync_service_.GetUserSettings()->GetSelectedTypes();
if (enabled) {
selected_sync_types.Put(syncer::UserSelectableType::kPreferences);
} else {
selected_sync_types.Remove(syncer::UserSelectableType::kPreferences);
}
test_sync_service_.GetUserSettings()->SetSelectedTypes(false,
selected_sync_types);
}
void PasswordManagerSettingsServiceAndroidImplBaseTest::
ExpectSettingsRetrievalFromBackend(std::optional<SyncingAccount> account,
size_t times) {
EXPECT_CALL(
*bridge_helper(),
GetPasswordSettingValue(
Eq(account), Eq(PasswordManagerSetting::kOfferToSavePasswords)))
.Times(times);
EXPECT_CALL(*bridge_helper(),
GetPasswordSettingValue(Eq(account),
Eq(PasswordManagerSetting::kAutoSignIn)))
.Times(times);
if (base::FeatureList::IsEnabled(
password_manager::features::kBiometricTouchToFill)) {
EXPECT_CALL(
*bridge_helper(),
GetPasswordSettingValue(
Eq(account),
Eq(PasswordManagerSetting::kBiometricReauthBeforePwdFilling)))
.Times(times);
}
}
void PasswordManagerSettingsServiceAndroidImplBaseTest::RegisterPrefs() {
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kCredentialsEnableService, true);
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kCredentialsEnableAutosignin, true);
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, true);
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kAutoSignInEnabledGMS, true);
test_pref_service_.registry()->RegisterStringPref(
::prefs::kGoogleServicesLastSyncingUsername, kTestAccount);
test_pref_service_.registry()->RegisterStringPref(
::prefs::kGoogleServicesLastSignedInUsername, kTestAccount);
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
false);
test_pref_service_.registry()->RegisterIntegerPref(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOff));
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kSettingsMigratedToUPMLocal, false);
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kEmptyProfileStoreLoginDatabase, false);
if (base::FeatureList::IsEnabled(
password_manager::features::kBiometricTouchToFill)) {
test_pref_service_.registry()->RegisterBooleanPref(
password_manager::prefs::kBiometricAuthenticationBeforeFilling, false);
}
}
// This suite starts with the pref `kPasswordsUseUPMLocalAndSeparateStores` off.
class PasswordManagerSettingsServiceAndroidImplTest
: public PasswordManagerSettingsServiceAndroidImplBaseTest {};
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
DoesntRequestSettingsOnServiceCreation) {
std::unique_ptr<MockPasswordSettingsUpdaterBridgeHelper> bridge_helper =
std::make_unique<MockPasswordSettingsUpdaterBridgeHelper>();
ASSERT_NE(bridge_helper, nullptr);
// The settings shouldn't be requested upon creating the service, which
// happens on startup, because Chrome also gets foregrounded and settings are
// requested on Chrome foregrounding.
EXPECT_CALL(*bridge_helper,
GetPasswordSettingValue(
Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kOfferToSavePasswords)))
.Times(0);
EXPECT_CALL(*bridge_helper,
GetPasswordSettingValue(Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kAutoSignIn)))
.Times(0);
SetPasswordsSync(true);
CreateNewService(std::move(bridge_helper));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingFetchSyncingBoth) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingFetchNotSyncingSettings) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingFetchNotSyncingPasswords) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInSettingFetchSyncingBoth) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, /*value=*/false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInFetchNotSyncingSettings) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, /*value=*/false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInFetchNotSyncingPasswords) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, /*value=*/false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingAbsentDefaultSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue(_, _, _)).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingAbsentDoesntSetValueSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(false));
// The settings for syncing users should no longer be written to GMSCore.
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kOfferToSavePasswords), false))
.Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingAbsentSetValueNotSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(false));
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue(_, _, _)).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnSaveSettingAbsentUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(false));
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue(_, _, _)).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInAbsentDefaultSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue(_, _, _)).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInAbsentDontSetValueSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(false));
// The settings for syncing users should no longer be written to GmsCore.
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kAutoSignIn), false))
.Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInAbsentSetValueNotSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(false));
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue(_, _, _)).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
OnAutoSignInAbsentSetValueUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(false));
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue(_, _, _)).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
}
// Checks that general syncable prefs are dumped into the android-only GMS
// prefs before settings are requested when sync is enabled.
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
PasswordSyncEnablingDoesntMovePrefs) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableService, base::Value(false));
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableAutosignin,
base::Value(false));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
SetPasswordsSync(/*enabled=*/true);
sync_service()->FireStateChanged();
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
// Checks that general syncable prefs are dumped into the android-only GMS
// prefs before settings are requested when sync is enabled.
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
PasswordSyncEnablingPrefsUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableService, base::Value(false));
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableAutosignin,
base::Value(false));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
SetPasswordsSync(/*enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
sync_service()->FireStateChanged();
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
PasswordSyncEnablingGMSSettingAbsentChromeHasUserSetting) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
pref_service()->SetBoolean(password_manager::prefs::kAutoSignInEnabledGMS,
false);
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
SetPasswordsSync(/*enabled=*/true);
sync_service()->FireStateChanged();
// For a syncing user, the setting stored in the account takes precedence and
// overwrites the local setting, even if the account setting has a default
// value.
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kCredentialsEnableAutosignin),
nullptr);
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kAutoSignInEnabledGMS),
nullptr);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
PasswordSyncEnablingGMSHasSetting) {
// TODO(crbug.com/40286015): Split this test.
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
SetPasswordsSync(/*enabled=*/true);
sync_service()->FireStateChanged();
// If the local setting in Chrome differs from the setting stored in the
// account, the account setting is stored in prefs and used.
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
PasswordSyncDisablingGMSSettingAbsent) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
pref_service()->SetBoolean(password_manager::prefs::kAutoSignInEnabledGMS,
false);
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
SetPasswordsSync(/*enabled=*/false);
sync_service()->FireStateChanged();
// Settings shouldn't be written to GMS Core.
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
PasswordSyncDisablingGMSHasSetting) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
SetPasswordsSync(/*enabled=*/false);
sync_service()->FireStateChanged();
// If the setting in Chrome differs from the setting in GMS Core, GMS Core
// setting is stored in prefs and used.
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SavePasswordsSettingNotSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableService, base::Value(true));
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(false));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SavePasswordsSettingSyncingManaged) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetManagedPref(
password_manager::prefs::kCredentialsEnableService, base::Value(false));
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(true));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SavePasswordsSettingSyncingNotManaged) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableService, base::Value(true));
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(false));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SavePasswordsSettingUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableService, base::Value(true));
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(false));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
AutoSignInSettingNotSyncing) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableAutosignin, base::Value(true));
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(false));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
AutoSignInSettingSyncingManaged) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetManagedPref(
password_manager::prefs::kCredentialsEnableAutosignin,
base::Value(false));
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(true));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
AutoSignInSettingSyncingNotManaged) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableAutosignin, base::Value(true));
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(false));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
AutoSignInSettingUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
pref_service()->SetUserPref(
password_manager::prefs::kCredentialsEnableAutosignin, base::Value(true));
pref_service()->SetUserPref(password_manager::prefs::kAutoSignInEnabledGMS,
base::Value(false));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SettingsAreRequestedFromBackendWhenPasswordSyncEnabled) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
settings_service()->RequestSettingsFromBackend();
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SettingsAreNotRequestedFromBackendWhenPasswordSyncDisabled) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/0);
settings_service()->RequestSettingsFromBackend();
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
SettingsAreNotRequestedFromBackendWhenUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/0);
settings_service()->RequestSettingsFromBackend();
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
TurnOffAutoSignInNotSyncingPasswords) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
settings_service()->TurnOffAutoSignIn();
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
TurnOffAutoSignInSyncingPasswordsNotPrefs) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kAutoSignIn), false))
.Times(1);
settings_service()->TurnOffAutoSignIn();
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
TurnOffAutoSignInSyncingPasswordsAndPrefs) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kAutoSignIn), false))
.Times(1);
settings_service()->TurnOffAutoSignIn();
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
TurnOffAutoSignInSyncingUserUnenrolledFromUPM) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
settings_service()->TurnOffAutoSignIn();
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
TestDontMigrateSettingsOnReenrollingIntoUPM) {
SetPasswordsSync(true);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
// Set an explicit value on the "Offer to save passwords" pref.
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
// Imitate reenrolment into UPM and triggering settings migration.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kAutoSignInEnabledGMS),
nullptr);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTest,
UnenrollmentPreventsRequestsOnSyncTurningOff) {
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
// Since the user was unenrolled and they don't have local backend support, it
// means that the backend is unreachable and instead the regular prefs are
// used, so there shouldn't be any backend request.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount), /*times=*/0);
SetPasswordsSync(/*enabled=*/false);
sync_service()->FireStateChanged();
}
// This suite starts with the pref `kPasswordsUseUPMLocalAndSeparateStores` on.
class PasswordManagerSettingsServiceAndroidImplTestLocalUsers
: public PasswordManagerSettingsServiceAndroidImplBaseTest {
protected:
PasswordManagerSettingsServiceAndroidImplTestLocalUsers() {
pref_service()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOn));
}
};
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
RespectsPolicyDespiteErrorOverrideForLocalBackend) {
// This test checks that the managed pref has a priority over the manually set
// values and that the password saving isn't suspended for users who are not
// syncing passwords.
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, false);
pref_service()->SetManagedPref(
password_manager::prefs::kCredentialsEnableService, base::Value(true));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
UnenrollmentDoesntPreventUPMLocalRequests) {
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
lifecycle_helper()->OnForegroundSessionStart();
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
UnenrollmentDoesntPreventUPMLocalOnSettingValueAbsent) {
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue).Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kCredentialsEnableAutosignin),
nullptr);
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kAutoSignInEnabledGMS),
nullptr);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
UnenrollmentDoesntPreventUPMLocalOnSettingValueFetched) {
pref_service()->SetBoolean(
password_manager::prefs::kUnenrolledFromGoogleMobileServicesDueToErrors,
true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(*bridge_helper(), SetPasswordSettingValue).Times(0);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetUserPrefValue(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetUserPrefValue(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
OnSaveSettingFetchUpdatesTheCacheAndRegularPref) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
OnSaveSettingFetchUpdatesOnlyTheCache) {
// This test is similar to OnSaveSettingFetchUpdatesTheCacheAndRegularPref,
// but it shows that the regular pref is not updated if settings sync is on,
// in order to prevent sync cycles.
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
OnSettingsAbsentUpdatesTheGMSAndRegularPref) {
// This test covers the case when the cache has a non-default value and GMS
// has a default value. The user can have non-default values in the cache
// while they're not yet syncing. When they start syncing, the cache will be
// overwritten by the value read from GMSCore, which could now be default,
// since it's now read from the storage for the account.
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, false);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS),
nullptr);
// The regular pref also needs to be overwritten because the user might drop
// out of the enabled group and will use the regular pref again.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kCredentialsEnableService),
nullptr);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
OnSettingsAbsentUpdatesOnlyTheGMSPref) {
// This test is similar to OnSettingsAbsentUpdatesTheGMSAndRegularPref, but
// it shows that the regular pref is not updated if settings sync is on, in
// order to prevent sync cycles.
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, false);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS),
nullptr);
// The regular pref should not be overwritten because settings are synced.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
IsSettingEnabledChecksGMSPrefWhenSettingsMigratedToUPMLocal) {
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
pref_service()->SetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, false);
// The settings migration happened so the setting from CMS Core is used.
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
RequestSettingsFromBackendFetchesSettings) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
settings_service()->RequestSettingsFromBackend();
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
TurnOffAutoSignInWhenNotSyncingSettingsChangesTheGMSPrefAndRegularPref) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(std::nullopt),
Eq(PasswordManagerSetting::kAutoSignIn), false));
settings_service()->TurnOffAutoSignIn();
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
TurnOffAutoSignInWhenSyncingSettingsChangesOnlyTheGMSPref) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
settings_service()->TurnOffAutoSignIn();
// The regular pref should not be updated because settings are synced.
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
PasswordSyncDisablingGMSSettingAbsent) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
SetPasswordsSync(/*enabled=*/false);
sync_service()->FireStateChanged();
// Settings shouldn't be written to GMS Core.
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kCredentialsEnableAutosignin),
nullptr);
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kAutoSignInEnabledGMS),
nullptr);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
PasswordSyncDisablingGMSHasSetting) {
InitializeSettingsService(/*password_sync_enabled=*/true,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
SetPasswordsSync(/*enabled=*/false);
sync_service()->FireStateChanged();
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
PasswordSyncEnablingGMSSettingAbsent) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
SetPasswordsSync(/*enabled=*/true);
sync_service()->FireStateChanged();
// Settings shouldn't be written to GMS Core.
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kCredentialsEnableAutosignin),
nullptr);
EXPECT_EQ(pref_service()->GetUserPrefValue(
password_manager::prefs::kAutoSignInEnabledGMS),
nullptr);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
PasswordSyncEnablingGMSHasSetting) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
// Settings should be requested from GMS Core on sync state change.
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount),
/*times=*/1);
SetPasswordsSync(/*enabled=*/true);
sync_service()->FireStateChanged();
// Settings shouldn't be written to GMS Core.
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, /*value=*/false);
// The old Chrome pref is also updated, because settings sync is off, so there
// is no risk of sync cycles.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
DoesntRequestSettingsOnServiceCreation) {
std::unique_ptr<MockPasswordSettingsUpdaterBridgeHelper> bridge_helper =
std::make_unique<MockPasswordSettingsUpdaterBridgeHelper>();
ASSERT_NE(bridge_helper, nullptr);
// The settings shouldn't be requested upon creating the service, which
// happens on startup, because Chrome also gets foregrounded and settings are
// requested on Chrome foregrounding.
EXPECT_CALL(*bridge_helper,
GetPasswordSettingValue(
Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kOfferToSavePasswords)))
.Times(0);
EXPECT_CALL(*bridge_helper,
GetPasswordSettingValue(Eq(SyncingAccount(kTestAccount)),
Eq(PasswordManagerSetting::kAutoSignIn)))
.Times(0);
SetPasswordsSync(false);
CreateNewService(std::move(bridge_helper));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
SavePasswordsSettingManagedByCustodian) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetSupervisedUserPref(
password_manager::prefs::kCredentialsEnableService, base::Value(false));
pref_service()->SetUserPref(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS,
base::Value(true));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsChromeHadNonDefaultValueGmsHadDefaultValue) {
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(std::nullopt),
Eq(PasswordManagerSetting::kAutoSignIn), false));
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
Eq(std::nullopt),
Eq(PasswordManagerSetting::kOfferToSavePasswords), false));
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, true);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, true);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
updater_bridge_consumer()->OnSuccessfulSettingChange(
PasswordManagerSetting::kAutoSignIn);
updater_bridge_consumer()->OnSuccessfulSettingChange(
PasswordManagerSetting::kOfferToSavePasswords);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsChromeAndGmsHadNonDefaultValue) {
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
pref_service()->SetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, false);
pref_service()->SetBoolean(password_manager::prefs::kAutoSignInEnabledGMS,
false);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(std::nullopt),
Eq(PasswordManagerSetting::kAutoSignIn), false));
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
Eq(std::nullopt),
Eq(PasswordManagerSetting::kOfferToSavePasswords), false));
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, false);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, false);
updater_bridge_consumer()->OnSuccessfulSettingChange(
PasswordManagerSetting::kAutoSignIn);
updater_bridge_consumer()->OnSuccessfulSettingChange(
PasswordManagerSetting::kOfferToSavePasswords);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
SettingsMigrationNotStartedIfCompletedBefore) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
Eq(std::nullopt),
Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
Eq(std::nullopt), Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, /*value=*/false);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, /*value=*/false);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsChromeAndGMSHadDefaultValue) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
lifecycle_helper()->OnForegroundSessionStart();
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kAutoSignIn);
updater_bridge_consumer()->OnSettingValueAbsent(
PasswordManagerSetting::kOfferToSavePasswords);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrationCallbackNotCreatedWhenChromeAndGMSHadDefaultValue) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
lifecycle_helper()->OnForegroundSessionStart();
// The Chrome settings were default, so the migration is marked as done.
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
// If the migration callback would have been created, despite the migration
// being marked as done, the following fetching errors would have been
// recorded in histograms. This is the only possible way to test if the
// callback was unnecessarily created because it can't be accessed directly
// and there are no mocks that would be related to the callback that can be
// tested to verify if the callback was created.
updater_bridge_consumer()->OnSettingFetchingError(
PasswordManagerSetting::kAutoSignIn,
AndroidBackendAPIErrorCode::kUnexpectedError);
updater_bridge_consumer()->OnSettingFetchingError(
PasswordManagerSetting::kOfferToSavePasswords,
AndroidBackendAPIErrorCode::kUnexpectedError);
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
histogram_tester()->ExpectBucketCount(
"PasswordManager.PasswordSettingsMigrationSucceeded2", false, 0);
histogram_tester()->ExpectBucketCount(
"PasswordManager.PasswordSettingsMigrationFailed.AutoSignIn.APIError2",
AndroidBackendAPIErrorCode::kUnexpectedError, 0);
histogram_tester()->ExpectBucketCount(
"PasswordManager.PasswordSettingsMigrationFailed.OfferToSavePasswords."
"APIError2",
AndroidBackendAPIErrorCode::kUnexpectedError, 0);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
SettingsMigrationNotPerformedWhenInterruptedByTurningOnSync) {
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
// The responses from GMS Core didn't yet come so the migration doesn't happen
// yet.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
ExpectSettingsRetrievalFromBackend(SyncingAccount(kTestAccount), /*times=*/1);
SetPasswordsSync(true);
sync_service()->FireStateChanged();
// The local settings migraton should not be performed, even though these
// calls will try to start it, because the user is syncing now.
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, false);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 0);
histogram_tester()->ExpectBucketCount(
"PasswordManager.PasswordSettingsMigrationSucceeded2", false, 0);
}
// Checks if settings migration happens only once per browser lifetime.
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsChromePutToForegroundTwice) {
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/2);
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, true);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, true);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
// Chrome gets put to the background and to the foreground again.
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, false);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
}
// Checks that the migration algorithm determines what to do for each setting
// independently from the other.
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsEachPrefHadDifferentValue) {
// User has changed one setting.
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(std::nullopt),
Eq(PasswordManagerSetting::kAutoSignIn), false));
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
lifecycle_helper()->OnForegroundSessionStart();
// GMS also had one setting changed, but it is different than the one in
// Chrome.
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, true);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
updater_bridge_consumer()->OnSuccessfulSettingChange(
PasswordManagerSetting::kAutoSignIn);
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsGettingValueFailed) {
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, true);
// The cached values are true until settings get fetched from GMS Core.
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
ASSERT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
lifecycle_helper()->OnForegroundSessionStart();
// Fetching the auto sign in setting fails.
updater_bridge_consumer()->OnSettingFetchingError(
PasswordManagerSetting::kAutoSignIn,
AndroidBackendAPIErrorCode::kUnexpectedError);
// Fetching the offer to save passwords setting succeeds and is different than
// the value in the Chrome setting.
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, true);
// Old Chrome settings stay intact.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
// The Cached GMS values in Chrome get updated on a successful fetch so offer
// to save passwords is now false.
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kAutoSignInEnabledGMS));
// The Chrome values get returned if the migration failed.
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
EXPECT_TRUE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
// Settings migration wasn't successful.
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationFailed.AutoSignIn.APIError2",
AndroidBackendAPIErrorCode::kUnexpectedError, 1);
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", false, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsMarkedAsDoneIfChromeHadDefaultPrefs) {
pref_service()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOn));
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", true, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrationNotDoneIfDefaultSettingsButNoStoreSplit) {
pref_service()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOff));
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectTotalCount(
"PasswordManager.PasswordSettingsMigrationSucceeded2", 0);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsGotValueForTheSamePrefTwice) {
// Set prefs to user selected value so that the migration is triggered
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
true);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
_, Eq(PasswordManagerSetting::kOfferToSavePasswords), _))
.Times(0);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(_, Eq(PasswordManagerSetting::kAutoSignIn), _))
.Times(0);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, false);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableService));
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", false, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
DefaultSettingsMigrationResetsIfLocalPwdMigrationOff) {
pref_service()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOff));
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
// Setting the settings migration pref to true to mimic the case when it was
// incorrectly set to true.
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
DefaultSettingsMigrationDoesntResetIfLocalPwdMigrationPending) {
pref_service()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::
kOffAndMigrationPending));
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
// Setting the settings migration pref to true to mimic the case when it was
// already set to true.
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
DefaultSettingsMigrationDoesntResetIfLocalPwdMigrationOn) {
pref_service()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOn));
pref_service()->ClearPref(password_manager::prefs::kCredentialsEnableService);
pref_service()->ClearPref(
password_manager::prefs::kCredentialsEnableAutosignin);
// Setting the settings migration pref to true to mimic the case when it was
// already set to true.
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
EXPECT_TRUE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
MigrateSettingsSettingGmsPrefFailed) {
pref_service()->SetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal, false);
pref_service()->SetBoolean(password_manager::prefs::kCredentialsEnableService,
false);
pref_service()->SetBoolean(
password_manager::prefs::kCredentialsEnableAutosignin, false);
pref_service()->SetBoolean(password_manager::prefs::kAutoSignInEnabledGMS,
true);
pref_service()->SetBoolean(
password_manager::prefs::kOfferToSavePasswordsEnabledGMS, true);
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
EXPECT_CALL(
*bridge_helper(),
SetPasswordSettingValue(Eq(std::nullopt),
Eq(PasswordManagerSetting::kAutoSignIn), false));
EXPECT_CALL(*bridge_helper(),
SetPasswordSettingValue(
Eq(std::nullopt),
Eq(PasswordManagerSetting::kOfferToSavePasswords), false));
lifecycle_helper()->OnForegroundSessionStart();
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kAutoSignIn, true);
updater_bridge_consumer()->OnSettingValueFetched(
PasswordManagerSetting::kOfferToSavePasswords, true);
updater_bridge_consumer()->OnSuccessfulSettingChange(
PasswordManagerSetting::kAutoSignIn);
updater_bridge_consumer()->OnFailedSettingChange(
PasswordManagerSetting::kOfferToSavePasswords,
AndroidBackendAPIErrorCode::kUnexpectedError);
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kOfferToSavePasswords));
EXPECT_FALSE(settings_service()->IsSettingEnabled(
PasswordManagerSetting::kAutoSignIn));
EXPECT_FALSE(pref_service()->GetBoolean(
password_manager::prefs::kSettingsMigratedToUPMLocal));
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationFailed.OfferToSavePasswords."
"APIError2",
AndroidBackendAPIErrorCode::kUnexpectedError, 1);
histogram_tester()->ExpectUniqueSample(
"PasswordManager.PasswordSettingsMigrationSucceeded2", false, 1);
}
TEST_F(PasswordManagerSettingsServiceAndroidImplTestLocalUsers,
FetchesBiometricAuthenticationBeforeFillingSetting) {
base::test::ScopedFeatureList scoped_feature_list{
password_manager::features::kBiometricTouchToFill};
InitializeSettingsService(/*password_sync_enabled=*/false,
/*setting_sync_enabled=*/false);
ExpectSettingsRetrievalFromBackend(std::nullopt, /*times=*/1);
lifecycle_helper()->OnForegroundSessionStart();
}