#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "chrome/browser/autofill/mock_manual_filling_view.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_address_accessory_controller.h"
#include "chrome/browser/password_manager/password_manager_settings_service_factory.h"
#include "chrome/browser/password_manager/profile_password_store_factory.h"
#include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
#include "chrome/browser/safe_browsing/user_interaction_observer.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
#include "chrome/browser/ui/passwords/password_cross_domain_confirmation_popup_controller_impl.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/autofill/content/browser/autofill_test_utils.h"
#include "components/autofill/content/browser/content_autofill_client.h"
#include "components/autofill/content/browser/content_autofill_driver.h"
#include "components/autofill/content/common/mojom/autofill_agent.mojom.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/logging/log_manager.h"
#include "components/autofill/core/browser/logging/log_receiver.h"
#include "components/autofill/core/browser/logging/log_router.h"
#include "components/autofill/core/browser/test_autofill_manager_waiter.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_test_utils.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/signatures.h"
#include "components/autofill/core/common/unique_ids.h"
#include "components/device_reauth/mock_device_authenticator.h"
#include "components/password_manager/content/browser/content_password_manager_driver.h"
#include "components/password_manager/content/browser/password_manager_log_router_factory.h"
#include "components/password_manager/core/browser/credential_cache.h"
#include "components/password_manager/core/browser/credentials_filter.h"
#include "components/password_manager/core/browser/mock_password_manager_settings_service.h"
#include "components/password_manager/core/browser/password_form.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store/mock_password_store_interface.h"
#include "components/password_manager/core/browser/password_store/password_store_consumer.h"
#include "components/password_manager/core/browser/split_stores_and_local_upm.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/safe_browsing/buildflags.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/sessions/content/content_record_password_state.h"
#include "components/sync/test/test_sync_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/mock_navigation_handle.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/web_contents_tester.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "url/url_constants.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#endif
#if BUILDFLAG(FULL_SAFE_BROWSING)
#include "components/safe_browsing/content/browser/password_protection/mock_password_protection_service.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "chrome/browser/autofill/mock_manual_filling_view.h"
#include "chrome/browser/keyboard_accessory/android/manual_filling_controller_impl.h"
#include "chrome/browser/keyboard_accessory/android/password_accessory_controller_impl.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_address_accessory_controller.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_manual_filling_controller.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_password_accessory_controller.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_payment_method_accessory_controller.h"
#include "chrome/browser/password_manager/account_password_store_factory.h"
#include "chrome/browser/password_manager/android/password_generation_controller.h"
#else
#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/browser/ui/hats/mock_hats_service.h"
#endif
CalculateFormSignature;
ContentAutofillClient;
ContentAutofillDriver;
FieldRendererId;
FormControlType;
FormData;
FormFieldData;
FocusedFieldType;
CreateFormDataForRenderFrameHost;
CreateTestFormField;
BrowserContext;
WebContents;
PasswordForm;
PasswordManagerClient;
PasswordManagerSetting;
PasswordStoreConsumer;
GetPasswordStateFromNavigation;
SerializedNavigationEntry;
_;
Key;
NiceMock;
Return;
SaveArg;
StrictMock;
UnorderedElementsAre;
#if BUILDFLAG(IS_ANDROID)
using base::android::BuildInfo;
using password_manager::CredentialCache;
using password_manager::MockPasswordStoreInterface;
#endif
namespace {
#if BUILDFLAG(IS_ANDROID)
FormData MakePasswordFormData() {
FormData form_data;
form_data.set_url(GURL("https://www.example.com/"));
form_data.set_action(GURL("https://www.example.com/"));
form_data.set_name(u"form-name");
FormFieldData field;
field.set_name(u"password-element");
field.set_id_attribute(field.name());
field.set_name_attribute(field.name());
field.set_form_control_type(autofill::FormControlType::kInputPassword);
field.set_renderer_id(FieldRendererId(123));
form_data.set_fields({field});
return form_data;
}
PasswordForm MakePasswordForm() {
PasswordForm form;
form.url = GURL("https://www.example.com/");
form.action = GURL("https://www.example.com/");
form.password_element = u"password-element";
form.submit_element = u"signIn";
form.signon_realm = "https://www.example.com/";
form.in_store = PasswordForm::Store::kProfileStore;
form.match_type = PasswordForm::MatchType::kExact;
return form;
}
#endif
class MockChromePasswordManagerClient : public ChromePasswordManagerClient { … };
class DummyLogReceiver : public autofill::LogReceiver { … };
class FakePasswordAutofillAgent
: public autofill::mojom::PasswordAutofillAgent { … };
#if BUILDFLAG(IS_ANDROID)
class MockPasswordAccessoryControllerImpl
: public PasswordAccessoryControllerImpl {
public:
MockPasswordAccessoryControllerImpl(
content::WebContents* web_contents,
password_manager::CredentialCache* credential_cache,
base::WeakPtr<ManualFillingController> mf_controller,
password_manager::PasswordManagerClient* password_client,
PasswordDriverSupplierForFocusedFrame driver_supplier)
: PasswordAccessoryControllerImpl(web_contents,
credential_cache,
mf_controller,
password_client,
driver_supplier,
base::DoNothing()) {}
MOCK_METHOD(void,
RefreshSuggestionsForField,
(autofill::mojom::FocusedFieldType),
(override));
MOCK_METHOD(void,
UpdateCredManReentryUi,
(autofill::mojom::FocusedFieldType),
(override));
};
#endif
std::unique_ptr<KeyedService> CreateTestSyncService(
content::BrowserContext* context) { … }
}
class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness { … };
void ChromePasswordManagerClientTest::SetUp() { … }
void ChromePasswordManagerClientTest::TearDown() { … }
ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() { … }
bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
bool* activation_flag) { … }
TEST_F(ChromePasswordManagerClientTest, LogEntryNotifyRenderer) { … }
TEST_F(ChromePasswordManagerClientTest,
SavingPasswordsTrueDeterminedByService) { … }
TEST_F(ChromePasswordManagerClientTest,
SavingPasswordsFalseDeterminedByService) { … }
TEST_F(ChromePasswordManagerClientTest, SavingAndFillingEnabledConditionsTest) { … }
TEST_F(ChromePasswordManagerClientTest,
SavingAndFillingDisabledConditionsInGuestAndIncognitoProfiles) { … }
TEST_F(ChromePasswordManagerClientTest, ReceivesAutofillPredictions) { … }
TEST_F(ChromePasswordManagerClientTest,
ReceivesAutofillPredictionsFromMultipleFrames) { … }
TEST_F(ChromePasswordManagerClientTest, AutoSignInEnabledDeterminedByService) { … }
TEST_F(ChromePasswordManagerClientTest,
AutoSignInDisableddDeterminedByService) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(ChromePasswordManagerClientTest, AutoSignInDisabledOnAutomotive) {
if (!BuildInfo::GetInstance()->is_automotive()) {
GTEST_SKIP() << "This test should only run on automotive.";
}
EXPECT_FALSE(GetClient()->IsAutoSignInEnabled());
}
#endif
class ChromePasswordManagerClientAutomatedTest
: public ChromePasswordManagerClientTest,
public testing::WithParamInterface<bool> { … };
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(ChromePasswordManagerClientAutomatedTest, SavingDependsOnAutomation) { … }
TEST_F(ChromePasswordManagerClientTest, SavingAndFillingDisabledForAboutBlank) { … }
TEST_F(ChromePasswordManagerClientTest,
IsFillingAndSavingOnGooglePasswordPage) { … }
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuthNoAuthenticator) {
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(
nullptr));
}
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuthNoBiometrics) {
device_reauth::MockDeviceAuthenticator authenticator;
local_state_.Get()->SetBoolean(
password_manager::prefs::kHadBiometricsAvailable, false);
profile()->GetTestingPrefService()->SetBoolean(
password_manager::prefs::kBiometricAuthenticationBeforeFilling, true);
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
}
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuthSettingDisabled) {
device_reauth::MockDeviceAuthenticator authenticator;
local_state_.Get()->SetBoolean(
password_manager::prefs::kHadBiometricsAvailable, true);
profile()->GetTestingPrefService()->SetBoolean(
password_manager::prefs::kBiometricAuthenticationBeforeFilling, false);
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
}
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuthSettingEnabled) {
device_reauth::MockDeviceAuthenticator authenticator;
local_state_.Get()->SetBoolean(
password_manager::prefs::kHadBiometricsAvailable, true);
profile()->GetTestingPrefService()->SetBoolean(
password_manager::prefs::kBiometricAuthenticationBeforeFilling, true);
EXPECT_TRUE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
}
#elif BUILDFLAG(IS_ANDROID)
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuthAndroid) {
if (base::android::BuildInfo::GetInstance()->is_automotive()) {
device_reauth::MockDeviceAuthenticator authenticator;
EXPECT_TRUE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
} else {
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(
nullptr));
}
}
TEST_F(ChromePasswordManagerClientTest,
CanUseBiometricAuthAndroidFeatureIsDisabled) {
if (base::android::BuildInfo::GetInstance()->is_automotive()) {
GTEST_SKIP();
}
device_reauth::MockDeviceAuthenticator authenticator;
ON_CALL(authenticator, CanAuthenticateWithBiometricOrScreenLock)
.WillByDefault(Return(true));
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
}
TEST_F(ChromePasswordManagerClientTest,
CanUseBiometricAuthAndroidAuthDisabled) {
if (base::android::BuildInfo::GetInstance()->is_automotive()) {
GTEST_SKIP();
}
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList enabled_features(
password_manager::features::kBiometricTouchToFill);
device_reauth::MockDeviceAuthenticator authenticator;
ON_CALL(authenticator, CanAuthenticateWithBiometricOrScreenLock)
.WillByDefault(Return(false));
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
histogram_tester.ExpectUniqueSample(
"PasswordManager.BiometricAuthPwdFillAndroid."
"CanAuthenticateWithBiometricOrScreenLock",
false, 1);
}
TEST_F(ChromePasswordManagerClientTest,
CanUseBiometricAuthAndroidPrefDisabled) {
if (base::android::BuildInfo::GetInstance()->is_automotive()) {
GTEST_SKIP();
}
base::test::ScopedFeatureList enabled_features(
password_manager::features::kBiometricTouchToFill);
device_reauth::MockDeviceAuthenticator authenticator;
ON_CALL(authenticator, CanAuthenticateWithBiometricOrScreenLock)
.WillByDefault(Return(true));
EXPECT_FALSE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
}
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuthAndroidAuthEnabled) {
if (base::android::BuildInfo::GetInstance()->is_automotive()) {
GTEST_SKIP();
}
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList enabled_features(
password_manager::features::kBiometricTouchToFill);
device_reauth::MockDeviceAuthenticator authenticator;
profile()->GetTestingPrefService()->SetBoolean(
password_manager::prefs::kBiometricAuthenticationBeforeFilling, true);
ON_CALL(authenticator, CanAuthenticateWithBiometricOrScreenLock)
.WillByDefault(Return(true));
EXPECT_TRUE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
histogram_tester.ExpectUniqueSample(
"PasswordManager.BiometricAuthPwdFillAndroid."
"CanAuthenticateWithBiometricOrScreenLock",
true, 1);
}
TEST_F(ChromePasswordManagerClientTest,
CanUseBiometricAuthAndroidAlwaysTrueOnAutomotive) {
if (!base::android::BuildInfo::GetInstance()->is_automotive()) {
GTEST_SKIP();
}
device_reauth::MockDeviceAuthenticator authenticator;
ON_CALL(authenticator, CanAuthenticateWithBiometricOrScreenLock)
.WillByDefault(Return(true));
EXPECT_TRUE(GetClient()->IsReauthBeforeFillingRequired(&authenticator));
}
#else
TEST_F(ChromePasswordManagerClientTest, CanUseBiometricAuth) { … }
#endif
namespace {
struct SchemeTestCase { … };
const SchemeTestCase kSchemeTestCases[] = …;
class ChromePasswordManagerClientSchemeTest
: public ChromePasswordManagerClientTest,
public ::testing::WithParamInterface<const char*> { … };
TEST_P(ChromePasswordManagerClientSchemeTest,
SavingAndFillingOnDifferentSchemes) { … }
INSTANTIATE_TEST_SUITE_P(…);
}
TEST_F(ChromePasswordManagerClientTest, GetLastCommittedEntryURL_Empty) { … }
TEST_F(ChromePasswordManagerClientTest, GetLastCommittedEntryURL) { … }
TEST_F(ChromePasswordManagerClientTest, WebUINoLogging) { … }
TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryUnannotated) { … }
TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryToFalse) { … }
TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryToTrue) { … }
TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryTrueToFalse) { … }
TEST_F(ChromePasswordManagerClientTest, BindCredentialManager_MissingInstance) { … }
TEST_F(ChromePasswordManagerClientTest, CanShowBubbleOnURL) { … }
#if !BUILDFLAG(IS_ANDROID)
TEST_F(ChromePasswordManagerClientTest,
TriggerUserPerceptionOfAutofillPasswordSurvey) { … }
TEST_F(
ChromePasswordManagerClientTest,
TriggerUserPerceptionOfAutofillPasswordSurvey_EmptyFillingAssistanceString_DoNotCallHats) { … }
#endif
#if BUILDFLAG(FULL_SAFE_BROWSING)
TEST_F(ChromePasswordManagerClientTest,
VerifyMaybeStartPasswordFieldOnFocusRequestCalled) { … }
TEST_F(ChromePasswordManagerClientTest,
SavingAndFillingDisabledConditionsDelayedWarnings) { … }
#endif
TEST_F(ChromePasswordManagerClientTest, MissingUIDelegate) { … }
#if BUILDFLAG(IS_ANDROID)
class ChromePasswordManagerClientAndroidTest
: public ChromePasswordManagerClientTest {
protected:
std::unique_ptr<password_manager::ContentPasswordManagerDriver>
CreateContentPasswordManagerDriver(content::RenderFrameHost* rfh);
void SetUp() override;
void CreateManualFillingController(content::WebContents* web_contents);
void SetUpGenerationPreconditions(const GURL& url);
MockPasswordAccessoryControllerImpl* SetUpMockPwdAccessoryForClientUse(
password_manager::PasswordManagerDriver* driver);
ManualFillingControllerImpl* controller() {
return ManualFillingControllerImpl::FromWebContents(web_contents());
}
MockManualFillingView* view() {
return static_cast<MockManualFillingView*>(controller()->view());
}
void AdvanceClock(const base::TimeDelta& delta) {
task_environment()->AdvanceClock(delta);
}
private:
NiceMock<MockPasswordAccessoryController> mock_pwd_controller_;
NiceMock<MockAddressAccessoryController> mock_address_controller_;
NiceMock<MockPaymentMethodAccessoryController>
mock_payment_method_controller_;
};
void ChromePasswordManagerClientAndroidTest::SetUp() {
ChromePasswordManagerClientTest::SetUp();
ProfilePasswordStoreFactory::GetInstance()->SetTestingFactory(
GetBrowserContext(),
base::BindRepeating(
&password_manager::BuildPasswordStoreInterface<
content::BrowserContext, MockPasswordStoreInterface>));
AccountPasswordStoreFactory::GetInstance()->SetTestingFactory(
GetBrowserContext(),
base::BindRepeating(
&password_manager::BuildPasswordStoreInterface<
content::BrowserContext, MockPasswordStoreInterface>));
PasswordManagerSettingsServiceFactory::GetInstance()->SetTestingFactory(
GetBrowserContext(),
base::BindRepeating([](content::BrowserContext* context)
-> std::unique_ptr<KeyedService> {
return std::make_unique<
NiceMock<password_manager::MockPasswordManagerSettingsService>>();
}));
}
std::unique_ptr<password_manager::ContentPasswordManagerDriver>
ChromePasswordManagerClientAndroidTest::CreateContentPasswordManagerDriver(
content::RenderFrameHost* rfh) {
return std::make_unique<password_manager::ContentPasswordManagerDriver>(
rfh, GetClient());
}
void ChromePasswordManagerClientAndroidTest::CreateManualFillingController(
content::WebContents* web_contents) {
ManualFillingControllerImpl::CreateForWebContentsForTesting(
web_contents, mock_pwd_controller_.AsWeakPtr(),
mock_address_controller_.AsWeakPtr(),
mock_payment_method_controller_.AsWeakPtr(),
std::make_unique<NiceMock<MockManualFillingView>>());
}
void ChromePasswordManagerClientAndroidTest::SetUpGenerationPreconditions(
const GURL& url) {
NavigateAndCommit(url);
ON_CALL(settings_service(),
IsSettingEnabled(PasswordManagerSetting::kOfferToSavePasswords))
.WillByDefault(Return(true));
sync_service()->SetIsUsingExplicitPassphrase(false);
sync_service()->GetUserSettings()->SetSelectedTypes(
false,
{syncer::UserSelectableType::kPasswords});
FocusWebContentsOnMainFrame();
}
MockPasswordAccessoryControllerImpl*
ChromePasswordManagerClientAndroidTest::SetUpMockPwdAccessoryForClientUse(
password_manager::PasswordManagerDriver* driver) {
base::RepeatingCallback<password_manager::PasswordManagerDriver*(
content::WebContents*)>
driver_supplier =
base::BindLambdaForTesting([=](WebContents*) { return driver; });
NiceMock<MockManualFillingController> mock_mf_controller;
std::unique_ptr<MockPasswordAccessoryControllerImpl> mock_pwd_controller =
std::make_unique<MockPasswordAccessoryControllerImpl>(
web_contents(), GetClient()->GetCredentialCacheForTesting(),
mock_mf_controller.AsWeakPtr(), GetClient(),
std::move(driver_supplier));
MockPasswordAccessoryControllerImpl* weak_mock_pwd_controller =
mock_pwd_controller.get();
web_contents()->SetUserData(weak_mock_pwd_controller->UserDataKey(),
std::move(mock_pwd_controller));
return weak_mock_pwd_controller;
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FocusedInputChangedNoFrameFillableField) {
CreateManualFillingController(web_contents());
ASSERT_FALSE(web_contents()->GetFocusedFrame());
ChromePasswordManagerClient* client = GetClient();
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
client->FocusedInputChanged(driver.get(), FieldRendererId(123),
FocusedFieldType::kFillablePasswordField);
PasswordGenerationController* pwd_generation_controller =
PasswordGenerationController::GetIfExisting(web_contents());
EXPECT_FALSE(pwd_generation_controller);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FocusedInputChangedNoFrameNoField) {
CreateManualFillingController(web_contents());
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
PasswordGenerationController* pwd_generation_controller =
PasswordGenerationController::GetOrCreate(web_contents());
pwd_generation_controller->FocusedInputChanged(
FocusedFieldType::kFillablePasswordField, driver->AsWeakPtrImpl());
ChromePasswordManagerClient* client = GetClient();
ASSERT_FALSE(web_contents()->GetFocusedFrame());
ASSERT_TRUE(pwd_generation_controller->GetActiveFrameDriver());
client->FocusedInputChanged(driver.get(), FieldRendererId(123),
FocusedFieldType::kUnknown);
EXPECT_FALSE(pwd_generation_controller->GetActiveFrameDriver());
}
TEST_F(ChromePasswordManagerClientAndroidTest, FocusedInputChangedWrongFrame) {
ChromePasswordManagerClient* client = GetClient();
NavigateAndCommit(GURL("https://example.com"));
FocusWebContentsOnMainFrame();
CreateManualFillingController(web_contents());
content::RenderFrameHost* subframe =
content::RenderFrameHostTester::For(main_rfh())->AppendChild("subframe");
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(subframe);
client->FocusedInputChanged(driver.get(), FieldRendererId(123),
FocusedFieldType::kFillablePasswordField);
PasswordGenerationController* pwd_generation_controller =
PasswordGenerationController::GetIfExisting(web_contents());
EXPECT_FALSE(pwd_generation_controller);
}
TEST_F(ChromePasswordManagerClientAndroidTest, FocusedInputChangedGoodFrame) {
ChromePasswordManagerClient* client = GetClient();
CreateManualFillingController(web_contents());
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
FocusWebContentsOnMainFrame();
client->FocusedInputChanged(driver.get(), FieldRendererId(123),
FocusedFieldType::kFillablePasswordField);
PasswordGenerationController* pwd_generation_controller =
PasswordGenerationController::GetIfExisting(web_contents());
EXPECT_TRUE(pwd_generation_controller);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FocusedInputChangedFormsNotFetchedMessagesFeature) {
FormData observed_form_data = MakePasswordFormData();
SetUpGenerationPreconditions(observed_form_data.url());
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
driver->GetPasswordManager()->OnPasswordFormsParsed(driver.get(),
{observed_form_data});
MockPasswordAccessoryControllerImpl* weak_mock_pwd_controller =
SetUpMockPwdAccessoryForClientUse(driver.get());
EXPECT_CALL(
*weak_mock_pwd_controller,
RefreshSuggestionsForField(FocusedFieldType::kFillablePasswordField));
GetClient()->FocusedInputChanged(driver.get(),
observed_form_data.fields()[0].renderer_id(),
FocusedFieldType::kFillablePasswordField);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
DISABLED_FocusedInputChangedFormsFetchedSplitStores) {
profile()->GetTestingPrefService()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOn));
FormData observed_form_data = MakePasswordFormData();
SetUpGenerationPreconditions(observed_form_data.url());
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
MockPasswordStoreInterface* mock_account_store =
static_cast<MockPasswordStoreInterface*>(
GetClient()->GetAccountPasswordStore());
base::WeakPtr<PasswordStoreConsumer> store_consumer;
EXPECT_CALL(*mock_account_store, IsAbleToSavePasswords)
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_account_store, GetLogins(_, _))
.WillOnce(SaveArg<1>(&store_consumer));
MockPasswordStoreInterface* mock_profile_store =
static_cast<MockPasswordStoreInterface*>(
GetClient()->GetProfilePasswordStore());
EXPECT_CALL(*mock_profile_store, GetLogins(_, _));
driver->GetPasswordManager()->OnPasswordFormsParsed(driver.get(),
{observed_form_data});
std::vector<PasswordForm> account_store_forms = {MakePasswordForm()};
store_consumer->OnGetPasswordStoreResultsOrErrorFrom(
mock_account_store, std::move(account_store_forms));
std::vector<PasswordForm> profile_store_forms = {MakePasswordForm()};
store_consumer->OnGetPasswordStoreResultsOrErrorFrom(
mock_profile_store, std::move(profile_store_forms));
MockPasswordAccessoryControllerImpl* weak_mock_pwd_controller =
SetUpMockPwdAccessoryForClientUse(driver.get());
EXPECT_CALL(
*weak_mock_pwd_controller,
RefreshSuggestionsForField(FocusedFieldType::kFillablePasswordField));
GetClient()->FocusedInputChanged(driver.get(),
observed_form_data.fields()[0].renderer_id(),
FocusedFieldType::kFillablePasswordField);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
DISABLED_FocusedInputChangedFormsFetchedSingleStore) {
profile()->GetTestingPrefService()->SetInteger(
password_manager::prefs::kPasswordsUseUPMLocalAndSeparateStores,
static_cast<int>(
password_manager::prefs::UseUpmLocalAndSeparateStoresState::kOff));
FormData observed_form_data = MakePasswordFormData();
SetUpGenerationPreconditions(observed_form_data.url());
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
base::WeakPtr<PasswordStoreConsumer> store_consumer;
MockPasswordStoreInterface* mock_profile_store =
static_cast<MockPasswordStoreInterface*>(
GetClient()->GetProfilePasswordStore());
EXPECT_CALL(*mock_profile_store, IsAbleToSavePasswords)
.WillRepeatedly(Return(true));
EXPECT_CALL(*mock_profile_store, GetLogins(_, _))
.WillOnce(SaveArg<1>(&store_consumer));
driver->GetPasswordManager()->OnPasswordFormsParsed(driver.get(),
{observed_form_data});
std::vector<PasswordForm> forms = {MakePasswordForm()};
store_consumer->OnGetPasswordStoreResultsOrErrorFrom(mock_profile_store,
std::move(forms));
MockPasswordAccessoryControllerImpl* weak_mock_pwd_controller =
SetUpMockPwdAccessoryForClientUse(driver.get());
EXPECT_CALL(
*weak_mock_pwd_controller,
RefreshSuggestionsForField(FocusedFieldType::kFillablePasswordField));
GetClient()->FocusedInputChanged(driver.get(),
observed_form_data.fields()[0].renderer_id(),
FocusedFieldType::kFillablePasswordField);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FocusedInputChangeUpdatesCredManReentryUi) {
std::unique_ptr<password_manager::ContentPasswordManagerDriver> driver =
CreateContentPasswordManagerDriver(main_rfh());
MockPasswordAccessoryControllerImpl* weak_mock_pwd_controller =
SetUpMockPwdAccessoryForClientUse(driver.get());
EXPECT_CALL(*weak_mock_pwd_controller, UpdateCredManReentryUi);
GetClient()->FocusedInputChanged(driver.get(), FieldRendererId(123),
FocusedFieldType::kFillablePasswordField);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
SameDocumentNavigationDoesNotClearCache) {
auto origin = url::Origin::Create(GURL("https://example.com"));
std::vector<PasswordForm> forms = {MakePasswordForm()};
GetClient()
->GetCredentialCacheForTesting()
->SaveCredentialsAndBlocklistedForOrigin(
forms, CredentialCache::IsOriginBlocklisted(false), origin);
content::MockNavigationHandle handle(web_contents());
handle.set_is_same_document(true);
handle.set_has_committed(true);
static_cast<content::WebContentsObserver*>(GetClient())
->DidFinishNavigation(&handle);
EXPECT_FALSE(GetClient()
->GetCredentialCacheForTesting()
->GetCredentialStore(origin)
.GetCredentials()
.empty());
NavigateAndCommit(GURL("https://example.org"));
EXPECT_TRUE(GetClient()
->GetCredentialCacheForTesting()
->GetCredentialStore(origin)
.GetCredentials()
.empty());
}
TEST_F(ChromePasswordManagerClientAndroidTest, HideFillingUIOnNavigatingAway) {
CreateManualFillingController(web_contents());
GURL kUrl1("https://example.com/");
NavigateAndCommit(kUrl1);
EXPECT_TRUE(ChromePasswordManagerClient::CanShowBubbleOnURL(kUrl1));
EXPECT_CALL(*view(), Hide());
GURL kUrl2("https://accounts.google.com");
NavigateAndCommit(kUrl2);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FormSubmissionTrackingAfterTouchToLogin_NotStarted) {
base::HistogramTester uma_recorder;
GetClient()->NotifyOnSuccessfulLogin(u"username");
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", 0);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FormSubmissionTrackingAfterTouchToLogin_Resetted) {
base::HistogramTester uma_recorder;
GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
GetClient()->ResetSubmissionTrackingAfterTouchToFill();
GetClient()->NotifyOnSuccessfulLogin(u"username");
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
uma_recorder.ExpectUniqueSample(
"PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false, 1);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FormSubmissionTrackingAfterTouchToLogin_AnotherUsername) {
base::HistogramTester uma_recorder;
GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
GetClient()->NotifyOnSuccessfulLogin(u"another_username");
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
uma_recorder.ExpectUniqueSample(
"PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false, 1);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FormSubmissionTrackingAfterTouchToLogin_StaleTracking) {
base::HistogramTester uma_recorder;
GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
AdvanceClock(base::Minutes(2));
GetClient()->NotifyOnSuccessfulLogin(u"username");
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.TimeToSuccessfulLogin", 0);
uma_recorder.ExpectUniqueSample(
"PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", false, 1);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
FormSubmissionTrackingAfterTouchToLogin_Succeeded) {
base::HistogramTester uma_recorder;
GetClient()->StartSubmissionTrackingAfterTouchToFill(u"username");
GetClient()->NotifyOnSuccessfulLogin(u"username");
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.TimeToSuccessfulLogin", 1);
uma_recorder.ExpectUniqueSample(
"PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", true, 1);
GetClient()->NotifyOnSuccessfulLogin(u"username");
uma_recorder.ExpectTotalCount(
"PasswordManager.TouchToFill.TimeToSuccessfulLogin", 1);
uma_recorder.ExpectUniqueSample(
"PasswordManager.TouchToFill.SuccessfulSubmissionWasObserved", true, 1);
}
TEST_F(ChromePasswordManagerClientAndroidTest,
RefreshPasswordManagerSettingsIfNeededUPMFeatureEnabled) {
EXPECT_CALL(settings_service(), RequestSettingsFromBackend);
GetClient()->RefreshPasswordManagerSettingsIfNeeded();
}
class ChromePasswordManagerClientWithAccountStoreAndroidTest
: public ChromePasswordManagerClientAndroidTest {
void SetUp() override {
base::android::BuildInfo::GetInstance()->set_gms_version_code_for_test(
base::NumberToString(password_manager::GetLocalUpmMinGmsVersion()));
ChromePasswordManagerClientAndroidTest::SetUp();
AccountPasswordStoreFactory::GetInstance()->SetTestingFactory(
GetBrowserContext(),
base::BindRepeating(
&password_manager::BuildPasswordStoreInterface<
content::BrowserContext, MockPasswordStoreInterface>));
}
};
TEST_F(ChromePasswordManagerClientWithAccountStoreAndroidTest,
MarkSharedCredentialsAsNotified) {
GURL kURL = GURL("https://example.com");
auto origin = url::Origin::Create(kURL);
auto not_shared = MakePasswordForm();
not_shared.username_value = u"not_shared";
auto shared_and_notified = MakePasswordForm();
shared_and_notified.username_value = u"shared_and_notified";
shared_and_notified.type = PasswordForm::Type::kReceivedViaSharing;
shared_and_notified.sharing_notification_displayed = true;
auto shared_not_notified_profile = MakePasswordForm();
shared_not_notified_profile.username_value = u"shared_not_notified_profile";
shared_not_notified_profile.type = PasswordForm::Type::kReceivedViaSharing;
shared_not_notified_profile.sharing_notification_displayed = false;
shared_not_notified_profile.in_store = PasswordForm::Store::kProfileStore;
auto shared_not_notified_account = MakePasswordForm();
shared_not_notified_account.username_value = u"shared_not_notified_account";
shared_not_notified_account.type = PasswordForm::Type::kReceivedViaSharing;
shared_not_notified_account.sharing_notification_displayed = false;
shared_not_notified_account.in_store = PasswordForm::Store::kAccountStore;
std::vector<PasswordForm> forms = {not_shared, shared_and_notified,
shared_not_notified_profile,
shared_not_notified_account};
GetClient()
->GetCredentialCacheForTesting()
->SaveCredentialsAndBlocklistedForOrigin(
forms, CredentialCache::IsOriginBlocklisted(false), origin);
MockPasswordStoreInterface* profile_store =
static_cast<MockPasswordStoreInterface*>(
GetClient()->GetProfilePasswordStore());
MockPasswordStoreInterface* account_store =
static_cast<MockPasswordStoreInterface*>(
GetClient()->GetAccountPasswordStore());
shared_not_notified_profile.sharing_notification_displayed = true;
shared_not_notified_account.sharing_notification_displayed = true;
EXPECT_CALL(*profile_store, UpdateLogin(shared_not_notified_profile, _));
EXPECT_CALL(*account_store, UpdateLogin(shared_not_notified_account, _));
GetClient()->MarkSharedCredentialsAsNotified(kURL);
}
#endif
#if !BUILDFLAG(IS_ANDROID)
class MockPasswordCrossDomainConfirmationPopupController
: public password_manager::PasswordCrossDomainConfirmationPopupController { … };
TEST_F(ChromePasswordManagerClientTest, ShowCrossDomainConfirmationPopup) { … }
#endif