Commit f6a72e0d authored by Vadym Doroshenko's avatar Vadym Doroshenko Committed by Commit Bot

Extract form filling from PasswordFormManager.

NewPasswordFormManager (details go/new-cpm-design-refactoring) will
send a fill message to the Renderer. This CL extracts this logic
from PasswordFormManager and PasswordManager to the separate file,
without changing any logic so that NewPasswordFormManager can reuse it.

Since now it is in a separate function, we can test it separately.
So unit tests were written.

Bug: 831123
Change-Id: Ibc448d7c287b1599bbbd8a721ca36a464b5b4a48
Reviewed-on: https://chromium-review.googlesource.com/1026111
Commit-Queue: Vadym Doroshenko <dvadym@chromium.org>
Reviewed-by: default avatarVaclav Brozek <vabr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555360}
parent 7fa584f7
......@@ -86,6 +86,8 @@ static_library("browser") {
"password_autofill_manager.h",
"password_bubble_experiment.cc",
"password_bubble_experiment.h",
"password_form_filling.cc",
"password_form_filling.h",
"password_form_manager.cc",
"password_form_manager.h",
"password_form_metrics_recorder.cc",
......@@ -351,6 +353,7 @@ source_set("unit_tests") {
"new_password_form_manager_unittest.cc",
"password_autofill_manager_unittest.cc",
"password_bubble_experiment_unittest.cc",
"password_form_filling_unittest.cc",
"password_form_manager_unittest.cc",
"password_form_metrics_recorder_unittest.cc",
"password_generation_manager_unittest.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/password_form_filling.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/password_form_fill_data.h"
#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
#include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
#include "components/password_manager/core/browser/password_form_metrics_recorder.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/common/password_manager_features.h"
using autofill::PasswordForm;
using autofill::PasswordFormFillData;
using Logger = autofill::SavePasswordProgressLogger;
namespace password_manager {
namespace {
bool PreferredRealmIsFromAndroid(const PasswordFormFillData& fill_data) {
return FacetURI::FromPotentiallyInvalidSpec(fill_data.preferred_realm)
.IsValidAndroidFacetURI();
}
bool ContainsAndroidCredentials(const PasswordFormFillData& fill_data) {
for (const auto& login : fill_data.additional_logins) {
if (FacetURI::FromPotentiallyInvalidSpec(login.second.realm)
.IsValidAndroidFacetURI()) {
return true;
}
}
return PreferredRealmIsFromAndroid(fill_data);
}
bool ShouldShowInitialPasswordAccountSuggestions() {
return base::FeatureList::IsEnabled(
password_manager::features::kFillOnAccountSelect);
}
void Autofill(const PasswordManagerClient& client,
PasswordManagerDriver* driver,
const PasswordForm& form_for_autofill,
const std::map<base::string16, const PasswordForm*>& best_matches,
const std::vector<const PasswordForm*>& federated_matches,
const PasswordForm& preferred_match,
bool wait_for_username) {
DCHECK_EQ(PasswordForm::SCHEME_HTML, preferred_match.scheme);
std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
if (password_manager_util::IsLoggingActive(&client)) {
logger.reset(new BrowserSavePasswordProgressLogger(client.GetLogManager()));
logger->LogMessage(Logger::STRING_PASSWORDMANAGER_AUTOFILL);
}
autofill::PasswordFormFillData fill_data;
InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match,
wait_for_username, false, &fill_data);
if (logger)
logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username);
UMA_HISTOGRAM_BOOLEAN(
"PasswordManager.FillSuggestionsIncludeAndroidAppCredentials",
ContainsAndroidCredentials(fill_data));
metrics_util::LogFilledCredentialIsFromAndroidApp(
PreferredRealmIsFromAndroid(fill_data));
driver->FillPasswordForm(fill_data);
client.PasswordWasAutofilled(best_matches, form_for_autofill.origin,
&federated_matches);
}
void ShowInitialPasswordAccountSuggestions(
const PasswordManagerClient& client,
PasswordManagerDriver* driver,
const PasswordForm& form_for_autofill,
const std::map<base::string16, const PasswordForm*>& best_matches,
const PasswordForm& preferred_match,
bool wait_for_username) {
DCHECK_EQ(PasswordForm::SCHEME_HTML, preferred_match.scheme);
std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
if (password_manager_util::IsLoggingActive(&client)) {
logger.reset(new BrowserSavePasswordProgressLogger(client.GetLogManager()));
logger->LogMessage(
Logger::
STRING_PASSWORDMANAGER_SHOW_INITIAL_PASSWORD_ACCOUNT_SUGGESTIONS);
}
PasswordFormFillData fill_data;
InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match,
wait_for_username, false, &fill_data);
if (logger)
logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username);
driver->ShowInitialPasswordAccountSuggestions(fill_data);
}
} // namespace
void SendFillInformationToRenderer(
const PasswordManagerClient& client,
PasswordManagerDriver* driver,
bool is_blacklisted,
const PasswordForm& observed_form,
const std::map<base::string16, const PasswordForm*>& best_matches,
const std::vector<const PasswordForm*>& federated_matches,
const PasswordForm* preferred_match,
PasswordFormMetricsRecorder* metrics_recorder) {
DCHECK(driver);
DCHECK_EQ(PasswordForm::SCHEME_HTML, observed_form.scheme);
if (is_blacklisted)
driver->MatchingBlacklistedFormFound();
driver->AllowPasswordGenerationForForm(observed_form);
if (best_matches.empty()) {
driver->InformNoSavedCredentials();
metrics_recorder->RecordFillEvent(
PasswordFormMetricsRecorder::kManagerFillEventNoCredential);
return;
}
DCHECK(preferred_match);
// Proceed to autofill.
// Note that we provide the choices but don't actually prefill a value if:
// (1) we are in Incognito mode, or
// (2) if it matched using public suffix domain matching, or
// (3) the form is change password form.
bool wait_for_username = client.IsIncognito() ||
preferred_match->is_public_suffix_match ||
observed_form.IsPossibleChangePasswordForm();
if (wait_for_username) {
metrics_recorder->SetManagerAction(
PasswordFormMetricsRecorder::kManagerActionNone);
metrics_recorder->RecordFillEvent(
PasswordFormMetricsRecorder::kManagerFillEventBlockedOnInteraction);
} else {
metrics_recorder->SetManagerAction(
PasswordFormMetricsRecorder::kManagerActionAutofilled);
metrics_recorder->RecordFillEvent(
PasswordFormMetricsRecorder::kManagerFillEventAutofilled);
base::RecordAction(base::UserMetricsAction("PasswordManager_Autofilled"));
}
if (ShouldShowInitialPasswordAccountSuggestions()) {
// This is for the fill-on-account-select experiment. Instead of autofilling
// found usernames and passwords on load, this instructs the renderer to
// return with any found password forms so a list of password account
// suggestions can be drawn.
ShowInitialPasswordAccountSuggestions(client, driver, observed_form,
best_matches, *preferred_match,
wait_for_username);
} else {
// If fill-on-account-select is not enabled, continue with autofilling any
// password forms as traditionally has been done.
Autofill(client, driver, observed_form, best_matches, federated_matches,
*preferred_match, wait_for_username);
}
}
} // namespace password_manager
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_FILLING_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_FILLING_H_
#include <map>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
namespace autofill {
struct PasswordForm;
} // namespace autofill
namespace password_manager {
class PasswordManagerClient;
class PasswordManagerDriver;
class PasswordFormMetricsRecorder;
void SendFillInformationToRenderer(
const PasswordManagerClient& client,
PasswordManagerDriver* driver,
bool is_blacklisted,
const autofill::PasswordForm& observed_form,
const std::map<base::string16, const autofill::PasswordForm*>& best_matches,
const std::vector<const autofill::PasswordForm*>& federated_matches,
const autofill::PasswordForm* preferred_match,
PasswordFormMetricsRecorder* metrics_recorder);
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_FILLING_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/password_form_filling.h"
#include <map>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/password_form_fill_data.h"
#include "components/password_manager/core/browser/password_form_metrics_recorder.h"
#include "components/password_manager/core/browser/stub_password_manager_client.h"
#include "components/password_manager/core/browser/stub_password_manager_driver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using autofill::PasswordForm;
using autofill::PasswordFormFillData;
using base::ASCIIToUTF16;
using testing::_;
using testing::SaveArg;
namespace password_manager {
namespace {
class MockPasswordManagerDriver : public StubPasswordManagerDriver {
public:
MockPasswordManagerDriver() {}
~MockPasswordManagerDriver() override {}
MOCK_METHOD1(FillPasswordForm, void(const PasswordFormFillData&));
MOCK_METHOD0(InformNoSavedCredentials, void());
MOCK_METHOD1(ShowInitialPasswordAccountSuggestions,
void(const PasswordFormFillData&));
MOCK_METHOD1(AllowPasswordGenerationForForm, void(const PasswordForm&));
MOCK_METHOD0(MatchingBlacklistedFormFound, void());
};
class MockPasswordManagerClient : public StubPasswordManagerClient {
public:
MockPasswordManagerClient() {}
MOCK_CONST_METHOD3(PasswordWasAutofilled,
void(const std::map<base::string16, const PasswordForm*>&,
const GURL&,
const std::vector<const PasswordForm*>*));
};
} // namespace
class PasswordFormFillingTest : public testing::Test {
public:
PasswordFormFillingTest() {
observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
observed_form_.action = GURL("http://accounts.google.com/a/Login");
observed_form_.username_element = ASCIIToUTF16("Email");
observed_form_.password_element = ASCIIToUTF16("Passwd");
observed_form_.submit_element = ASCIIToUTF16("signIn");
observed_form_.signon_realm = "http://accounts.google.com";
observed_form_.form_data.name = ASCIIToUTF16("the-form-name");
saved_match_ = observed_form_;
saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
saved_match_.preferred = true;
saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
saved_match_.password_value = ASCIIToUTF16("test1");
psl_saved_match_ = saved_match_;
psl_saved_match_.is_public_suffix_match = true;
psl_saved_match_.origin =
GURL("http://m.accounts.google.com/a/ServiceLoginAuth");
psl_saved_match_.action = GURL("http://m.accounts.google.com/a/Login");
psl_saved_match_.signon_realm = "http://m.accounts.google.com";
metrics_recorder_ = base::MakeRefCounted<PasswordFormMetricsRecorder>(
true, client_.GetUkmSourceId());
}
protected:
MockPasswordManagerDriver driver_;
MockPasswordManagerClient client_;
PasswordForm observed_form_;
PasswordForm saved_match_;
PasswordForm psl_saved_match_;
scoped_refptr<PasswordFormMetricsRecorder> metrics_recorder_;
std::vector<const autofill::PasswordForm*> federated_matches_;
};
TEST_F(PasswordFormFillingTest, NoSavedCredentials) {
std::map<base::string16, const autofill::PasswordForm*> best_matches;
EXPECT_CALL(driver_, AllowPasswordGenerationForForm(observed_form_));
EXPECT_CALL(driver_, InformNoSavedCredentials());
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
EXPECT_CALL(driver_, ShowInitialPasswordAccountSuggestions(_)).Times(0);
SendFillInformationToRenderer(
client_, &driver_, false /* is_blacklisted */, observed_form_,
best_matches, federated_matches_, nullptr, metrics_recorder_.get());
}
TEST_F(PasswordFormFillingTest, Autofill) {
for (bool is_blacklisted : {false, true}) {
std::map<base::string16, const autofill::PasswordForm*> best_matches;
best_matches[saved_match_.username_value] = &saved_match_;
PasswordForm another_saved_match = saved_match_;
another_saved_match.username_value += ASCIIToUTF16("1");
another_saved_match.password_value += ASCIIToUTF16("1");
best_matches[another_saved_match.username_value] = &another_saved_match;
EXPECT_CALL(driver_, AllowPasswordGenerationForForm(observed_form_));
EXPECT_CALL(driver_, InformNoSavedCredentials()).Times(0);
PasswordFormFillData fill_data;
EXPECT_CALL(driver_, FillPasswordForm(_)).WillOnce(SaveArg<0>(&fill_data));
EXPECT_CALL(driver_, ShowInitialPasswordAccountSuggestions(_)).Times(0);
EXPECT_CALL(client_, PasswordWasAutofilled(_, _, _));
EXPECT_CALL(driver_, MatchingBlacklistedFormFound)
.Times(is_blacklisted ? 1 : 0);
SendFillInformationToRenderer(
client_, &driver_, is_blacklisted, observed_form_, best_matches,
federated_matches_, &saved_match_, metrics_recorder_.get());
// Check that the message to the renderer (i.e. |fill_data|) is filled
// correctly.
EXPECT_EQ(observed_form_.origin, fill_data.origin);
EXPECT_FALSE(fill_data.wait_for_username);
EXPECT_EQ(observed_form_.username_element, fill_data.username_field.name);
EXPECT_EQ(saved_match_.username_value, fill_data.username_field.value);
EXPECT_EQ(observed_form_.password_element, fill_data.password_field.name);
EXPECT_EQ(saved_match_.password_value, fill_data.password_field.value);
// Check that information about non-preferred best matches is filled.
ASSERT_EQ(1u, fill_data.additional_logins.size());
EXPECT_EQ(another_saved_match.username_value,
fill_data.additional_logins.begin()->first);
EXPECT_EQ(another_saved_match.password_value,
fill_data.additional_logins.begin()->second.password);
// Realm is empty for non-psl match.
EXPECT_TRUE(fill_data.additional_logins.begin()->second.realm.empty());
}
}
TEST_F(PasswordFormFillingTest, AutofillPSLMatch) {
std::map<base::string16, const autofill::PasswordForm*> best_matches;
best_matches[saved_match_.username_value] = &psl_saved_match_;
EXPECT_CALL(driver_, AllowPasswordGenerationForForm(observed_form_));
EXPECT_CALL(driver_, InformNoSavedCredentials()).Times(0);
PasswordFormFillData fill_data;
EXPECT_CALL(driver_, FillPasswordForm(_)).WillOnce(SaveArg<0>(&fill_data));
EXPECT_CALL(driver_, ShowInitialPasswordAccountSuggestions(_)).Times(0);
EXPECT_CALL(client_, PasswordWasAutofilled(_, _, _));
SendFillInformationToRenderer(client_, &driver_, false /* is_blacklisted */,
observed_form_, best_matches,
federated_matches_, &psl_saved_match_,
metrics_recorder_.get());
// Check that the message to the renderer (i.e. |fill_data|) is filled
// correctly.
EXPECT_EQ(observed_form_.origin, fill_data.origin);
EXPECT_TRUE(fill_data.wait_for_username);
EXPECT_EQ(psl_saved_match_.signon_realm, fill_data.preferred_realm);
EXPECT_EQ(observed_form_.username_element, fill_data.username_field.name);
EXPECT_EQ(saved_match_.username_value, fill_data.username_field.value);
EXPECT_EQ(observed_form_.password_element, fill_data.password_field.name);
EXPECT_EQ(saved_match_.password_value, fill_data.password_field.value);
}
} // namespace password_manager
......@@ -12,7 +12,6 @@
#include <memory>
#include <utility>
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
......@@ -30,6 +29,7 @@
#include "components/password_manager/core/browser/form_fetcher_impl.h"
#include "components/password_manager/core/browser/form_saver.h"
#include "components/password_manager/core/browser/log_manager.h"
#include "components/password_manager/core/browser/password_form_filling.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
......@@ -65,11 +65,6 @@ bool IsProbablyNotUsername(const base::string16& s) {
return !s.empty() && DoesStringContainOnlyDigits(s) && s.size() < 3;
}
bool ShouldShowInitialPasswordAccountSuggestions() {
return base::FeatureList::IsEnabled(
password_manager::features::kFillOnAccountSelect);
}
// Update |credential| to reflect usage.
void UpdateMetadataForUsage(PasswordForm* credential) {
++credential->times_used;
......@@ -632,57 +627,12 @@ void PasswordFormManager::ProcessFrame(
void PasswordFormManager::ProcessFrameInternal(
const base::WeakPtr<PasswordManagerDriver>& driver) {
DCHECK_EQ(PasswordForm::SCHEME_HTML, observed_form_.scheme);
if (!driver)
return;
if (IsBlacklisted())
driver->MatchingBlacklistedFormFound();
driver->AllowPasswordGenerationForForm(observed_form_);
if (best_matches_.empty()) {
driver->InformNoSavedCredentials();
metrics_recorder_->RecordFillEvent(
PasswordFormMetricsRecorder::kManagerFillEventNoCredential);
return;
}
// Proceed to autofill.
// Note that we provide the choices but don't actually prefill a value if:
// (1) we are in Incognito mode, or
// (2) if it matched using public suffix domain matching, or
// (3) the form is change password form.
bool wait_for_username = client_->IsIncognito() ||
preferred_match_->is_public_suffix_match ||
observed_form_.IsPossibleChangePasswordForm();
if (wait_for_username) {
metrics_recorder_->SetManagerAction(
PasswordFormMetricsRecorder::kManagerActionNone);
metrics_recorder_->RecordFillEvent(
PasswordFormMetricsRecorder::kManagerFillEventBlockedOnInteraction);
} else {
metrics_recorder_->SetManagerAction(
PasswordFormMetricsRecorder::kManagerActionAutofilled);
metrics_recorder_->RecordFillEvent(
PasswordFormMetricsRecorder::kManagerFillEventAutofilled);
base::RecordAction(base::UserMetricsAction("PasswordManager_Autofilled"));
}
if (ShouldShowInitialPasswordAccountSuggestions()) {
// This is for the fill-on-account-select experiment. Instead of autofilling
// found usernames and passwords on load, this instructs the renderer to
// return with any found password forms so a list of password account
// suggestions can be drawn.
password_manager_->ShowInitialPasswordAccountSuggestions(
driver.get(), observed_form_, best_matches_, *preferred_match_,
wait_for_username);
} else {
// If fill-on-account-select is not enabled, continue with autofilling any
// password forms as traditionally has been done.
password_manager_->Autofill(driver.get(), observed_form_, best_matches_,
SendFillInformationToRenderer(*client_, driver.get(), IsBlacklisted(),
observed_form_, best_matches_,
form_fetcher_->GetFederatedMatches(),
*preferred_match_, wait_for_username);
}
preferred_match_, metrics_recorder());
}
void PasswordFormManager::ProcessLoginPrompt() {
......
......@@ -20,7 +20,6 @@
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/common/form_data_predictions.h"
#include "components/autofill/core/common/password_form_field_prediction_map.h"
#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
#include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
#include "components/password_manager/core/browser/form_saver_impl.h"
#include "components/password_manager/core/browser/keychain_migration_status_mac.h"
......@@ -160,24 +159,6 @@ bool IsPredictedTypeNotPasswordPrediction(
field_type == autofill::CREDIT_CARD_VERIFICATION_CODE;
}
bool PreferredRealmIsFromAndroid(
const autofill::PasswordFormFillData& fill_data) {
return FacetURI::FromPotentiallyInvalidSpec(
fill_data.preferred_realm).IsValidAndroidFacetURI();
}
bool ContainsAndroidCredentials(
const autofill::PasswordFormFillData& fill_data) {
for (const auto& login : fill_data.additional_logins) {
if (FacetURI::FromPotentiallyInvalidSpec(
login.second.realm).IsValidAndroidFacetURI()) {
return true;
}
}
return PreferredRealmIsFromAndroid(fill_data);
}
bool AreAllFieldsEmpty(const PasswordForm& form) {
return form.username_value.empty() && form.password_value.empty() &&
form.new_password_value.empty();
......@@ -958,64 +939,6 @@ void PasswordManager::OnLoginSuccessful() {
}
}
void PasswordManager::Autofill(
password_manager::PasswordManagerDriver* driver,
const PasswordForm& form_for_autofill,
const std::map<base::string16, const PasswordForm*>& best_matches,
const std::vector<const PasswordForm*>& federated_matches,
const PasswordForm& preferred_match,
bool wait_for_username) const {
DCHECK_EQ(PasswordForm::SCHEME_HTML, preferred_match.scheme);
std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
if (password_manager_util::IsLoggingActive(client_)) {
logger.reset(
new BrowserSavePasswordProgressLogger(client_->GetLogManager()));
logger->LogMessage(Logger::STRING_PASSWORDMANAGER_AUTOFILL);
}
autofill::PasswordFormFillData fill_data;
InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match,
wait_for_username, OtherPossibleUsernamesEnabled(),
&fill_data);
if (logger)
logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username);
UMA_HISTOGRAM_BOOLEAN(
"PasswordManager.FillSuggestionsIncludeAndroidAppCredentials",
ContainsAndroidCredentials(fill_data));
metrics_util::LogFilledCredentialIsFromAndroidApp(
PreferredRealmIsFromAndroid(fill_data));
driver->FillPasswordForm(fill_data);
client_->PasswordWasAutofilled(best_matches, form_for_autofill.origin,
&federated_matches);
}
void PasswordManager::ShowInitialPasswordAccountSuggestions(
password_manager::PasswordManagerDriver* driver,
const PasswordForm& form_for_autofill,
const std::map<base::string16, const PasswordForm*>& best_matches,
const PasswordForm& preferred_match,
bool wait_for_username) const {
DCHECK_EQ(PasswordForm::SCHEME_HTML, preferred_match.scheme);
std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
if (password_manager_util::IsLoggingActive(client_)) {
logger.reset(
new BrowserSavePasswordProgressLogger(client_->GetLogManager()));
logger->LogMessage(
Logger::
STRING_PASSWORDMANAGER_SHOW_INITIAL_PASSWORD_ACCOUNT_SUGGESTIONS);
}
autofill::PasswordFormFillData fill_data;
InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match,
wait_for_username, OtherPossibleUsernamesEnabled(),
&fill_data);
if (logger)
logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username);
driver->ShowInitialPasswordAccountSuggestions(fill_data);
}
void PasswordManager::AutofillHttpAuth(
const std::map<base::string16, const PasswordForm*>& best_matches,
const PasswordForm& preferred_match) const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment