Commit ed62618c authored by Caitlin Fischer's avatar Caitlin Fischer Committed by Commit Bot

[Autofill] Added ability to make suggestion label formats.

The formatter creator is in charge of constructing the appropriate formatter.
Formatters are responsible for producing labels according to the formatter
type.

These labels contain disambiguating information to display to users in the
Autofill dropdown.

Change-Id: Ia63ab173e4449dc744d7ee39ea887494466dff29
Reviewed-on: https://chromium-review.googlesource.com/c/1489181
Commit-Queue: Caitlin Fischer <caitlinfischer@google.com>
Reviewed-by: default avatarFabio Tirelo <ftirelo@chromium.org>
Reviewed-by: default avatarTommy Martino <tmartino@chromium.org>
Auto-Submit: Caitlin Fischer <caitlinfischer@google.com>
Cr-Commit-Position: refs/heads/master@{#636831}
parent 2db13360
...@@ -125,6 +125,9 @@ jumbo_static_library("browser") { ...@@ -125,6 +125,9 @@ jumbo_static_library("browser") {
"form_structure.h", "form_structure.h",
"form_types.cc", "form_types.cc",
"form_types.h", "form_types.h",
"label_formatter.h",
"label_formatter_creator.cc",
"label_formatter_creator.h",
"legacy_strike_database.cc", "legacy_strike_database.cc",
"legacy_strike_database.h", "legacy_strike_database.h",
"legal_message_line.cc", "legal_message_line.cc",
...@@ -140,8 +143,12 @@ jumbo_static_library("browser") { ...@@ -140,8 +143,12 @@ jumbo_static_library("browser") {
"metrics/form_event_logger_base.cc", "metrics/form_event_logger_base.cc",
"metrics/form_event_logger_base.h", "metrics/form_event_logger_base.h",
"metrics/form_events.h", "metrics/form_events.h",
"name_and_address_disclosure_label_formatter.cc",
"name_and_address_disclosure_label_formatter.h",
"name_field.cc", "name_field.cc",
"name_field.h", "name_field.h",
"name_phone_and_email_disclosure_label_formatter.cc",
"name_phone_and_email_disclosure_label_formatter.h",
"password_requirements_spec_fetcher.h", "password_requirements_spec_fetcher.h",
"password_requirements_spec_fetcher_impl.cc", "password_requirements_spec_fetcher_impl.cc",
"password_requirements_spec_fetcher_impl.h", "password_requirements_spec_fetcher_impl.h",
...@@ -537,6 +544,7 @@ source_set("unit_tests") { ...@@ -537,6 +544,7 @@ source_set("unit_tests") {
"form_data_importer_unittest.cc", "form_data_importer_unittest.cc",
"form_field_unittest.cc", "form_field_unittest.cc",
"form_structure_unittest.cc", "form_structure_unittest.cc",
"label_formatter_creator_unittest.cc",
"legacy_strike_database_unittest.cc", "legacy_strike_database_unittest.cc",
"legal_message_line_unittest.cc", "legal_message_line_unittest.cc",
"local_card_migration_manager_unittest.cc", "local_card_migration_manager_unittest.cc",
......
// Copyright 2019 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_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
#include <string>
#include <vector>
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/field_types.h"
namespace autofill {
// Handles the creation of Suggestions' disambiguating labels.
class LabelFormatter {
public:
virtual ~LabelFormatter() = default;
// Returns a collection of |labels| formed by extracting useful disambiguating
// information from a collection of |profiles|.
virtual std::vector<base::string16> GetLabels(
const std::vector<AutofillProfile*>& profiles) const = 0;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
// Copyright 2019 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 <memory>
#include <set>
#include "components/autofill/core/browser/label_formatter_creator.h"
#include "components/autofill/core/browser/name_and_address_disclosure_label_formatter.h"
#include "components/autofill/core/browser/name_phone_and_email_disclosure_label_formatter.h"
namespace autofill {
namespace {
// Returns true if |type| belongs to the NAME FieldTypeGroup. Note that billing
// ServerFieldTypes are converted to their non-billing types.
bool FieldTypeIsName(const ServerFieldType& type) {
FieldTypeGroup focused_field_group =
AutofillType(AutofillType(type).GetStorableType()).group();
return focused_field_group == NAME;
}
} // namespace
uint32_t DetermineGroups(const std::vector<ServerFieldType>& field_types) {
uint32_t group_bitmask = 0;
for (const ServerFieldType& type : field_types) {
const FieldTypeGroup group =
AutofillType(AutofillType(type).GetStorableType()).group();
switch (group) {
case autofill::NAME:
group_bitmask |= label_formatter_groups::kName;
break;
case autofill::ADDRESS_HOME:
group_bitmask |= label_formatter_groups::kAddress;
break;
case autofill::EMAIL:
group_bitmask |= label_formatter_groups::kEmail;
break;
case autofill::PHONE_HOME:
group_bitmask |= label_formatter_groups::kPhone;
break;
default:
group_bitmask |= label_formatter_groups::kUnsupported;
}
}
return group_bitmask;
}
std::unique_ptr<LabelFormatter> Create(
const std::string& app_locale,
ServerFieldType focused_field_type,
const std::vector<ServerFieldType>& field_types) {
if (!FieldTypeIsName(focused_field_type)) {
return nullptr;
}
std::vector<ServerFieldType> filtered_field_types;
for (const ServerFieldType& field_type : field_types) {
// NO_SERVER_DATA fields are frequently found in the collection of field
// types sent from the frontend. UKNOWN_TYPE fields represent various form
// elements, e.g. checkboxes. Neither field type is useful to the formatter,
// so they are excluded from its collection of field types.
if (field_type != NO_SERVER_DATA && field_type != UNKNOWN_TYPE) {
filtered_field_types.push_back(field_type);
}
}
const uint32_t groups = DetermineGroups(filtered_field_types);
if (groups ==
(label_formatter_groups::kName | label_formatter_groups::kAddress)) {
return std::make_unique<NameAndAddressDisclosureLabelFormatter>(
app_locale, focused_field_type, filtered_field_types);
}
if (groups ==
(label_formatter_groups::kName | label_formatter_groups::kPhone |
label_formatter_groups::kEmail)) {
return std::make_unique<NamePhoneAndEmailDisclosureLabelFormatter>(
app_locale, focused_field_type, filtered_field_types);
}
return nullptr;
}
} // namespace autofill
// Copyright 2019 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_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_CREATOR_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_CREATOR_H_
#include <memory>
#include <string>
#include <vector>
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/label_formatter.h"
namespace autofill {
namespace label_formatter_groups {
// Bits for FieldTypeGroup options.
// The form contains an unsupported field.
constexpr uint32_t kUnsupported = 1 << 0;
// The form contains at least one field associated with the NAME_HOME or
// NAME_BILLING FieldTypeGroups.
constexpr uint32_t kName = 1 << 1;
// The form contains at least one field associated with the ADDRESS_HOME or
// ADDRESS_BILLING FieldTypeGroups.
constexpr uint32_t kAddress = 1 << 2;
// The form contains at least one field associated with the EMAIL
// FieldTypeGroup.
constexpr uint32_t kEmail = 1 << 3;
// The form contains at least one field associated with the PHONE_HOME or
// PHONE_BILLING FieldTypeGroup.
constexpr uint32_t kPhone = 1 << 4;
} // namespace label_formatter_groups
// Returns a bitmask indicating the FieldTypeGroups associated with the given
// |field_types|.
uint32_t DetermineGroups(const std::vector<ServerFieldType>& field_types);
// Creates a form-specific LabelFormatter according to |field_types|. If the
// given |focused_field_type| and |field_types| do not correspond to a
// LabelFormatter, then nullptr will be returned.
std::unique_ptr<LabelFormatter> Create(
const std::string& app_locale,
ServerFieldType focused_field_type,
const std::vector<ServerFieldType>& field_types);
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_CREATOR_H_
// Copyright 2019 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/autofill/core/browser/label_formatter_creator.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
using label_formatter_groups::kAddress;
using label_formatter_groups::kEmail;
using label_formatter_groups::kName;
using label_formatter_groups::kPhone;
using label_formatter_groups::kUnsupported;
} // namespace
TEST(LabelFormatterCreatorTest, DetermineGroupsForHomeNameAndAddress) {
const std::vector<ServerFieldType> field_types{
NAME_FIRST, NAME_LAST, ADDRESS_HOME_LINE1,
ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP};
const uint32_t expected_group_bitmask = kName | kAddress;
const uint32_t group_bitmask = DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
TEST(LabelFormatterCreatorTest, DetermineGroupsForBillingNameAndAddress) {
const std::vector<ServerFieldType> field_types{
NAME_BILLING_FULL, ADDRESS_BILLING_LINE1, ADDRESS_BILLING_CITY,
ADDRESS_BILLING_STATE, ADDRESS_BILLING_ZIP};
const uint32_t expected_group_bitmask = kName | kAddress;
const uint32_t group_bitmask = DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
TEST(LabelFormatterCreatorTest, DetermineGroupsForNameHomePhoneAndEmail) {
const std::vector<ServerFieldType> field_types{
NAME_FULL, PHONE_HOME_CITY_AND_NUMBER, EMAIL_ADDRESS};
const uint32_t expected_group_bitmask = kName | kPhone | kEmail;
const uint32_t group_bitmask = DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
TEST(LabelFormatterCreatorTest, DetermineGroupsForNameBillingPhoneAndEmail) {
const std::vector<ServerFieldType> field_types{
NAME_BILLING_FULL, PHONE_BILLING_WHOLE_NUMBER, EMAIL_ADDRESS};
const uint32_t expected_group_bitmask = kName | kPhone | kEmail;
const uint32_t group_bitmask = DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
TEST(LabelFormatterCreatorTest, DetermineGroupsForUnknownServerFieldType) {
const std::vector<ServerFieldType> field_types{UNKNOWN_TYPE, NAME_FULL,
ADDRESS_HOME_ZIP};
const uint32_t expected_group_bitmask = kName | kAddress | kUnsupported;
const uint32_t group_bitmask = DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
TEST(LabelFormatterCreatorTest, DetermineGroupsForNoServerFieldTypes) {
const std::vector<ServerFieldType> field_types =
std::vector<ServerFieldType>();
const uint32_t expected_group_bitmask = 0;
const uint32_t group_bitmask = DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
} // namespace autofill
// Copyright 2019 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/autofill/core/browser/name_and_address_disclosure_label_formatter.h"
namespace autofill {
NameAndAddressDisclosureLabelFormatter::NameAndAddressDisclosureLabelFormatter(
const std::string& app_locale,
ServerFieldType focused_field_type,
const std::vector<ServerFieldType>& field_types)
: app_locale_(app_locale),
focused_field_type_(focused_field_type),
field_types_(field_types) {
for (const ServerFieldType& type : field_types) {
if ((type != ADDRESS_HOME_COUNTRY) && (type != ADDRESS_BILLING_COUNTRY) &&
(type != focused_field_type_)) {
filtered_field_types_.push_back(type);
}
}
}
NameAndAddressDisclosureLabelFormatter::
~NameAndAddressDisclosureLabelFormatter() {}
std::vector<base::string16> NameAndAddressDisclosureLabelFormatter::GetLabels(
const std::vector<AutofillProfile*>& profiles) const {
// TODO(crbug.com/936168): Implement GetLabels().
std::vector<base::string16> labels;
return labels;
}
} // namespace autofill
// Copyright 2019 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_AUTOFILL_CORE_BROWSER_NAME_AND_ADDRESS_DISCLOSURE_LABEL_FORMATTER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_NAME_AND_ADDRESS_DISCLOSURE_LABEL_FORMATTER_H_
#include <string>
#include <vector>
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/label_formatter.h"
namespace autofill {
// A LabelFormatter that uses the disclosure approach to create Suggestions'
// disambiguating labels for forms exclusively containing name and address
// fields.
class NameAndAddressDisclosureLabelFormatter : public LabelFormatter {
public:
explicit NameAndAddressDisclosureLabelFormatter(
const std::string& app_locale,
ServerFieldType focused_field_type,
const std::vector<ServerFieldType>& field_types);
~NameAndAddressDisclosureLabelFormatter() override;
std::vector<base::string16> GetLabels(
const std::vector<AutofillProfile*>& profiles) const override;
private:
// The locale for which to generate labels. This reflects the language and
// country for which the application is translated, e.g. en_AU for Austalian
// English.
std::string app_locale_;
// The field on which the user is currently focused.
ServerFieldType focused_field_type_;
// A collection of meaningful field types in the form with which the user is
// interacting. The NO_SERVER_DATA and UNKNOWN_TYPE field types are not
// considered meaningful.
std::vector<ServerFieldType> field_types_;
// A collection of meaningful field types excluding the focused_field_type_
// and ADDRESS_HOME_COUNTRY and ADDRESS_BILLING_COUNTRY. These types are used
// to construct the labels.
std::vector<ServerFieldType> filtered_field_types_;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_NAME_AND_ADDRESS_DISCLOSURE_LABEL_FORMATTER_H_
// Copyright 2019 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/autofill/core/browser/name_phone_and_email_disclosure_label_formatter.h"
namespace autofill {
NamePhoneAndEmailDisclosureLabelFormatter::
NamePhoneAndEmailDisclosureLabelFormatter(
const std::string& app_locale,
ServerFieldType focused_field_type,
const std::vector<ServerFieldType>& field_types)
: app_locale_(app_locale),
focused_field_type_(focused_field_type),
field_types_(field_types) {
for (const ServerFieldType& type : field_types) {
if (type != focused_field_type_) {
filtered_field_types_.push_back(type);
}
}
}
NamePhoneAndEmailDisclosureLabelFormatter::
~NamePhoneAndEmailDisclosureLabelFormatter() {}
std::vector<base::string16>
NamePhoneAndEmailDisclosureLabelFormatter::GetLabels(
const std::vector<AutofillProfile*>& profiles) const {
// TODO(crbug.com/936168): Implement GetLabels().
std::vector<base::string16> labels;
return labels;
}
} // namespace autofill
// Copyright 2019 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_AUTOFILL_CORE_BROWSER_NAME_PHONE_AND_EMAIL_DISCLOSURE_LABEL_FORMATTER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_NAME_PHONE_AND_EMAIL_DISCLOSURE_LABEL_FORMATTER_H_
#include <string>
#include <vector>
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/label_formatter.h"
namespace autofill {
// A LabelFormatter that uses the disclosure approach to create Suggestions'
// disambiguating labels for forms exclusively containing name, phone, and email
// fields.
class NamePhoneAndEmailDisclosureLabelFormatter : public LabelFormatter {
public:
explicit NamePhoneAndEmailDisclosureLabelFormatter(
const std::string& app_locale,
ServerFieldType focused_field_type,
const std::vector<ServerFieldType>& field_types);
~NamePhoneAndEmailDisclosureLabelFormatter() override;
std::vector<base::string16> GetLabels(
const std::vector<AutofillProfile*>& profiles) const override;
private:
// The locale for which to generate labels. This reflects the language and
// country for which the application is translated, e.g. en_AU for Austalian
// English.
std::string app_locale_;
// The field on which the user is currently focused.
ServerFieldType focused_field_type_;
// A collection of meaningful field types in the form with which the user is
// interacting. The NO_SERVER_DATA and UNKNOWN_TYPE field types are not
// considered meaningful.
std::vector<ServerFieldType> field_types_;
// A collection of meaningful field types excluding the focused_field_type_.
// These types are used to construct the labels.
std::vector<ServerFieldType> filtered_field_types_;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_NAME_PHONE_AND_EMAIL_DISCLOSURE_LABEL_FORMATTER_H_
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