// Copyright 2018 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/keyboard_accessory/android/accessory_sheet_data.h"
#include "base/base64.h"
#include "base/logging.h"
#include "base/ranges/algorithm.h"
#include "chrome/browser/keyboard_accessory/android/accessory_sheet_enums.h"
namespace autofill {
AccessorySheetField::AccessorySheetField() = default;
AccessorySheetField::AccessorySheetField(const AccessorySheetField&) = default;
AccessorySheetField::AccessorySheetField(AccessorySheetField&&) = default;
AccessorySheetField::~AccessorySheetField() = default;
AccessorySheetField& AccessorySheetField::operator=(
const AccessorySheetField&) = default;
AccessorySheetField& AccessorySheetField::operator=(AccessorySheetField&&) =
default;
std::ostream& operator<<(std::ostream& os, const AccessorySheetField& field) {
os << "(display text: \"" << field.display_text() << "\", "
<< "text_to_fill: \"" << field.text_to_fill() << "\", "
<< "a11y_description: \"" << field.a11y_description() << "\", " << "id: \""
<< field.id() << "\", " << "icon_id: \"" << field.icon_id() << "\", "
<< "is " << (field.selectable() ? "" : "not ") << "selectable, " << "is "
<< (field.is_obfuscated() ? "" : "not ") << "obfuscated)";
return os;
}
AccessorySheetField::Builder::Builder() = default;
AccessorySheetField::Builder::~Builder() = default;
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetDisplayText(
std::u16string display_text) && {
// Calls SetDisplayText(...)& since |this| is an lvalue.
accessory_sheet_field_.set_display_text(std::move(display_text));
return std::move(*this);
}
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetTextToFill(
std::u16string text_to_fill) && {
accessory_sheet_field_.set_text_to_fill(std::move(text_to_fill));
return std::move(*this);
}
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetA11yDescription(
std::u16string a11y_description) && {
accessory_sheet_field_.set_a11y_description(std::move(a11y_description));
return std::move(*this);
}
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetId(
std::string id) && {
accessory_sheet_field_.set_id(std::move(id));
return std::move(*this);
}
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetIsObfuscated(
bool is_obfuscated) && {
accessory_sheet_field_.set_is_obfuscated(is_obfuscated);
return std::move(*this);
}
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetSelectable(
bool selectable) && {
accessory_sheet_field_.set_selectable(selectable);
return std::move(*this);
}
AccessorySheetField::Builder&& AccessorySheetField::Builder::SetIconId(
int icon_id) && {
accessory_sheet_field_.set_icon_id(icon_id);
return std::move(*this);
}
AccessorySheetField&& AccessorySheetField::Builder::Build() && {
if (accessory_sheet_field_.text_to_fill().empty()) {
accessory_sheet_field_.set_text_to_fill(
accessory_sheet_field_.display_text());
}
if (accessory_sheet_field_.a11y_description().empty()) {
accessory_sheet_field_.set_a11y_description(
accessory_sheet_field_.display_text());
}
return std::move(accessory_sheet_field_);
}
UserInfo::UserInfo() = default;
UserInfo::UserInfo(std::string origin)
: UserInfo(std::move(origin), IsExactMatch(true)) {}
UserInfo::UserInfo(std::string origin, IsExactMatch is_exact_match)
: UserInfo(std::move(origin), is_exact_match, GURL()) {}
UserInfo::UserInfo(std::string origin, GURL icon_url)
: UserInfo(std::move(origin), IsExactMatch(true), std::move(icon_url)) {}
UserInfo::UserInfo(std::string origin,
IsExactMatch is_exact_match,
GURL icon_url)
: origin_(std::move(origin)),
is_exact_match_(is_exact_match),
icon_url_(std::move(icon_url)) {}
UserInfo::UserInfo(const UserInfo&) = default;
UserInfo& UserInfo::operator=(const UserInfo&) = default;
UserInfo::UserInfo(UserInfo&&) = default;
UserInfo& UserInfo::operator=(UserInfo&&) = default;
UserInfo::~UserInfo() = default;
std::ostream& operator<<(std::ostream& os, const UserInfo& user_info) {
os << "origin: \"" << user_info.origin() << "\", "
<< "is_exact_match: " << std::boolalpha << user_info.is_exact_match()
<< ", "
<< "icon_url: " << user_info.icon_url() << ","
<< "fields: [\n";
for (const AccessorySheetField& field : user_info.fields()) {
os << field << ", \n";
}
return os << "]";
}
UserInfoSection::UserInfoSection(std::u16string title)
: title_(std::move(title)) {}
UserInfoSection::UserInfoSection(const UserInfoSection&) = default;
UserInfoSection& UserInfoSection::operator=(const UserInfoSection&) = default;
UserInfoSection::UserInfoSection(UserInfoSection&&) = default;
UserInfoSection& UserInfoSection::operator=(UserInfoSection&&) = default;
UserInfoSection::~UserInfoSection() = default;
std::ostream& operator<<(std::ostream& os, const UserInfoSection& section) {
os << "with title: \"" << section.title() << "\" and user info list: [";
for (const UserInfo& user_info : section.user_info_list()) {
os << user_info << ", ";
}
os << "]";
return os;
}
PlusAddressInfo::PlusAddressInfo(std::string origin,
std::u16string plus_address)
: origin_(std::move(origin)),
plus_address_(AccessorySheetField::Builder()
.SetDisplayText(std::move(plus_address))
.SetSelectable(true)
.Build()) {}
PlusAddressInfo::PlusAddressInfo(const PlusAddressInfo&) = default;
PlusAddressInfo& PlusAddressInfo::operator=(const PlusAddressInfo&) = default;
PlusAddressInfo::PlusAddressInfo(PlusAddressInfo&&) = default;
PlusAddressInfo& PlusAddressInfo::operator=(PlusAddressInfo&&) = default;
PlusAddressInfo::~PlusAddressInfo() = default;
std::ostream& operator<<(std::ostream& os,
const PlusAddressInfo& plus_address) {
os << "origin: \"" << plus_address.origin() << "\", " << "plus_address: \""
<< plus_address.plus_address().display_text() << "\"";
return os;
}
PlusAddressSection::PlusAddressSection(std::u16string title)
: title_(std::move(title)) {}
PlusAddressSection::PlusAddressSection(const PlusAddressSection&) = default;
PlusAddressSection& PlusAddressSection::operator=(const PlusAddressSection&) =
default;
PlusAddressSection::PlusAddressSection(PlusAddressSection&&) = default;
PlusAddressSection& PlusAddressSection::operator=(PlusAddressSection&&) =
default;
PlusAddressSection::~PlusAddressSection() = default;
std::ostream& operator<<(std::ostream& os,
const PlusAddressSection& plus_address_section) {
os << "title: \"" << plus_address_section.title()
<< "\", plus address info list: [";
for (const PlusAddressInfo& info :
plus_address_section.plus_address_info_list()) {
os << info << ", ";
}
os << "]";
return os;
}
PasskeySection::PasskeySection(std::string display_name,
std::vector<uint8_t> passkey_id)
: display_name_(std::move(display_name)),
passkey_id_(std::move(passkey_id)) {}
PasskeySection::PasskeySection(const PasskeySection&) = default;
PasskeySection& PasskeySection::operator=(const PasskeySection&) = default;
PasskeySection::PasskeySection(PasskeySection&&) = default;
PasskeySection& PasskeySection::operator=(PasskeySection&&) = default;
PasskeySection::~PasskeySection() = default;
std::ostream& operator<<(std::ostream& os,
const PasskeySection& passkey_section) {
os << "display_name: \"" << passkey_section.display_name() << "\", "
<< "passkey_id: \"" << base::Base64Encode(passkey_section.passkey_id())
<< "\"";
return os;
}
PromoCodeInfo::PromoCodeInfo(std::u16string promo_code,
std::u16string details_text)
: promo_code_(AccessorySheetField::Builder()
.SetDisplayText(std::move(promo_code))
.SetSelectable(true)
.Build()),
details_text_(details_text) {}
PromoCodeInfo::PromoCodeInfo(const PromoCodeInfo&) = default;
PromoCodeInfo& PromoCodeInfo::operator=(const PromoCodeInfo&) = default;
PromoCodeInfo::PromoCodeInfo(PromoCodeInfo&&) = default;
PromoCodeInfo& PromoCodeInfo::operator=(PromoCodeInfo&&) = default;
PromoCodeInfo::~PromoCodeInfo() = default;
std::ostream& operator<<(std::ostream& os,
const PromoCodeInfo& promo_code_info) {
os << "promo_code: \"" << promo_code_info.promo_code() << "\", "
<< "details_text: \"" << promo_code_info.details_text() << "\"";
return os;
}
IbanInfo::IbanInfo(std::u16string value,
std::u16string text_to_fill,
std::string id)
: value_(AccessorySheetField::Builder()
.SetDisplayText(std::move(value))
.SetTextToFill(std::move(text_to_fill))
.SetId(std::move(id))
.SetSelectable(true)
.Build()) {}
IbanInfo::IbanInfo(const IbanInfo&) = default;
IbanInfo& IbanInfo::operator=(const IbanInfo&) = default;
IbanInfo::IbanInfo(IbanInfo&&) = default;
IbanInfo& IbanInfo::operator=(IbanInfo&&) = default;
IbanInfo::~IbanInfo() = default;
std::ostream& operator<<(std::ostream& os, const IbanInfo& iban_info) {
os << "iban_info: \"" << iban_info.value() << "\"";
return os;
}
FooterCommand::FooterCommand(std::u16string display_text,
AccessoryAction action)
: display_text_(std::move(display_text)), accessory_action_(action) {}
FooterCommand::FooterCommand(const FooterCommand&) = default;
FooterCommand& FooterCommand::operator=(const FooterCommand&) = default;
FooterCommand& FooterCommand::operator=(FooterCommand&&) = default;
FooterCommand::FooterCommand(FooterCommand&&) = default;
FooterCommand::~FooterCommand() = default;
std::ostream& operator<<(std::ostream& os, const FooterCommand& fc) {
return os << "(display text: \"" << fc.display_text() << "\", "
<< "action: " << static_cast<int>(fc.accessory_action()) << ")";
}
OptionToggle::OptionToggle(std::u16string display_text,
bool enabled,
AccessoryAction action)
: display_text_(display_text),
enabled_(enabled),
accessory_action_(action) {}
OptionToggle::OptionToggle(const OptionToggle&) = default;
OptionToggle& OptionToggle::operator=(const OptionToggle&) = default;
OptionToggle::OptionToggle(OptionToggle&&) = default;
OptionToggle& OptionToggle::operator=(OptionToggle&&) = default;
OptionToggle::~OptionToggle() = default;
std::ostream& operator<<(std::ostream& os, const OptionToggle& ot) {
return os << "(display text: \"" << ot.display_text() << "\", "
<< "state: " << ot.is_enabled() << ", "
<< "action: " << static_cast<int>(ot.accessory_action()) << ")";
}
std::ostream& operator<<(std::ostream& os, const AccessoryTabType& type) {
switch (type) {
case AccessoryTabType::PASSWORDS:
return os << "Passwords sheet";
case AccessoryTabType::CREDIT_CARDS:
return os << "Payments sheet";
case AccessoryTabType::ADDRESSES:
return os << "Address sheet";
case AccessoryTabType::OBSOLETE_TOUCH_TO_FILL:
return os << "(obsolete) Touch to Fill sheet";
case AccessoryTabType::ALL:
return os << "All sheets";
case AccessoryTabType::COUNT:
return os << "Invalid sheet";
}
return os;
}
AccessorySheetData::AccessorySheetData(AccessoryTabType sheet_type,
std::u16string user_info_title,
std::u16string plus_address_title)
: AccessorySheetData(sheet_type,
std::move(user_info_title),
std::move(plus_address_title),
std::u16string()) {}
AccessorySheetData::AccessorySheetData(AccessoryTabType sheet_type,
std::u16string user_info_title,
std::u16string plus_address_title,
std::u16string warning)
: sheet_type_(sheet_type),
warning_(std::move(warning)),
plus_address_section_(std::move(plus_address_title)),
user_info_section_(std::move(user_info_title)) {}
AccessorySheetData::AccessorySheetData(const AccessorySheetData&) = default;
AccessorySheetData& AccessorySheetData::operator=(const AccessorySheetData&) =
default;
AccessorySheetData::AccessorySheetData(AccessorySheetData&&) = default;
AccessorySheetData& AccessorySheetData::operator=(AccessorySheetData&&) =
default;
AccessorySheetData::~AccessorySheetData() = default;
std::ostream& operator<<(std::ostream& os, const AccessorySheetData& data) {
os << data.get_sheet_type();
if (data.option_toggle().has_value()) {
os << "\", with option toggle: \"" << data.option_toggle().value();
} else {
os << "\", with option toggle: \"none";
}
os << "\", warning: \"" << data.warning() << "\", and passkey list: [";
for (const PasskeySection& passkey_section : data.passkey_section_list()) {
os << passkey_section << ", ";
}
os << "], and user info section " << data.user_info_section();
os << ", and promo code info list: [";
for (const PromoCodeInfo& promo_code_info : data.promo_code_info_list()) {
os << promo_code_info << ", ";
}
os << "], and iban info list: [";
for (const IbanInfo& iban_info : data.iban_info_list()) {
os << iban_info << ", ";
}
os << "], and plus address section: " << data.plus_address_section();
os << ", footer commands: [";
for (const FooterCommand& footer_command : data.footer_commands()) {
os << footer_command << ", ";
}
return os << "]";
}
AccessorySheetData::Builder::Builder(AccessoryTabType type,
std::u16string user_info_title,
std::u16string plus_address_title)
: accessory_sheet_data_(type,
std::move(user_info_title),
std::move(plus_address_title)) {}
AccessorySheetData::Builder::~Builder() = default;
AccessorySheetData::Builder&& AccessorySheetData::Builder::SetWarning(
std::u16string warning) && {
// Calls SetWarning(std::u16string warning)()& since |this| is an lvalue.
return std::move(SetWarning(std::move(warning)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::SetWarning(
std::u16string warning) & {
accessory_sheet_data_.set_warning(std::move(warning));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::SetOptionToggle(
std::u16string display_text,
bool enabled,
AccessoryAction action) && {
// Calls SetOptionToggle(...)& since |this| is an lvalue.
return std::move(SetOptionToggle(std::move(display_text), enabled, action));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::SetOptionToggle(
std::u16string display_text,
bool enabled,
AccessoryAction action) & {
accessory_sheet_data_.set_option_toggle(
OptionToggle(std::move(display_text), enabled, action));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AddUserInfo(
std::string origin,
UserInfo::IsExactMatch is_exact_match,
GURL icon_url) && {
// Calls AddUserInfo()& since |this| is an lvalue.
return std::move(
AddUserInfo(std::move(origin), is_exact_match, std::move(icon_url)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AddUserInfo(
std::string origin,
UserInfo::IsExactMatch is_exact_match,
GURL icon_url) & {
accessory_sheet_data_.add_user_info(
UserInfo(std::move(origin), is_exact_match, std::move(icon_url)));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AppendSimpleField(
std::u16string text) && {
// Calls AppendSimpleField(...)& since |this| is an lvalue.
return std::move(AppendSimpleField(std::move(text)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AppendSimpleField(
std::u16string text) & {
std::u16string display_text = text;
std::u16string text_to_fill = text;
std::u16string a11y_description = std::move(text);
return AppendField(std::move(display_text), std::move(text_to_fill),
std::move(a11y_description), false, true);
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AppendField(
std::u16string display_text,
std::u16string a11y_description,
bool is_obfuscated,
bool selectable) && {
std::u16string text_to_fill = display_text;
// Calls AppendField(...)& since |this| is an lvalue.
return std::move(AppendField(std::move(display_text), std::move(text_to_fill),
std::move(a11y_description), is_obfuscated,
selectable));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AppendField(
std::u16string display_text,
std::u16string text_to_fill,
std::u16string a11y_description,
bool is_obfuscated,
bool selectable) & {
accessory_sheet_data_.mutable_user_info_list().back().add_field(
AccessorySheetField::Builder()
.SetDisplayText(std::move(display_text))
.SetTextToFill(std::move(text_to_fill))
.SetA11yDescription(std::move(a11y_description))
.SetIsObfuscated(is_obfuscated)
.SetSelectable(selectable)
.Build());
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AppendField(
std::u16string display_text,
std::u16string text_to_fill,
std::u16string a11y_description,
std::string id,
bool is_obfuscated,
bool selectable) && {
// Calls AppendField(...)& since |this| is an lvalue.
return std::move(AppendField(std::move(display_text), std::move(text_to_fill),
std::move(a11y_description), std::move(id),
is_obfuscated, selectable));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AppendField(
std::u16string display_text,
std::u16string text_to_fill,
std::u16string a11y_description,
std::string id,
bool is_obfuscated,
bool selectable) & {
accessory_sheet_data_.mutable_user_info_list().back().add_field(
AccessorySheetField::Builder()
.SetDisplayText(std::move(display_text))
.SetTextToFill(std::move(text_to_fill))
.SetA11yDescription(std::move(a11y_description))
.SetId(std::move(id))
.SetIsObfuscated(is_obfuscated)
.SetSelectable(selectable)
.Build());
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AppendField(
std::u16string display_text,
std::u16string text_to_fill,
std::u16string a11y_description,
std::string id,
int icon_id,
bool is_obfuscated,
bool selectable) && {
accessory_sheet_data_.mutable_user_info_list().back().add_field(
AccessorySheetField::Builder()
.SetDisplayText(std::move(display_text))
.SetTextToFill(std::move(text_to_fill))
.SetA11yDescription(std::move(a11y_description))
.SetId(std::move(id))
.SetIconId(icon_id)
.SetIsObfuscated(is_obfuscated)
.SetSelectable(selectable)
.Build());
return std::move(*this);
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AddPlusAddressInfo(
std::string origin,
std::u16string plus_address) && {
// Calls AddPlusAddressInfo(...)& since |this| is an lvalue.
return std::move(
AddPlusAddressInfo(std::move(origin), std::move(plus_address)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AddPlusAddressInfo(
std::string origin,
std::u16string plus_address) & {
accessory_sheet_data_.add_plus_address_info(
(PlusAddressInfo(std::move(origin), std::move(plus_address))));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AddPasskeySection(
std::string username,
std::vector<uint8_t> credential_id) && {
// Calls PasskeySection(...)& since |this| is an lvalue.
return std::move(
AddPasskeySection(std::move(username), std::move(credential_id)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AddPasskeySection(
std::string username,
std::vector<uint8_t> credential_id) & {
accessory_sheet_data_.add_passkey_section(
(PasskeySection(std::move(username), std::move(credential_id))));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AddPromoCodeInfo(
std::u16string promo_code,
std::u16string details_text) && {
// Calls PromoCodeInfo(...)& since |this| is an lvalue.
return std::move(
AddPromoCodeInfo(std::move(promo_code), std::move(details_text)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AddPromoCodeInfo(
std::u16string promo_code,
std::u16string details_text) & {
accessory_sheet_data_.add_promo_code_info(
(PromoCodeInfo(std::move(promo_code), std::move(details_text))));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AddIbanInfo(
std::u16string value,
std::u16string text_to_fill,
std::string id) && {
// Calls IbanInfo(...)& since `this` is an lvalue.
return std::move(
AddIbanInfo(std::move(value), std::move(text_to_fill), std::move(id)));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AddIbanInfo(
std::u16string value,
std::u16string text_to_fill,
std::string id) & {
accessory_sheet_data_.add_iban_info(
(IbanInfo(std::move(value), std::move(text_to_fill), std::move(id))));
return *this;
}
AccessorySheetData::Builder&& AccessorySheetData::Builder::AppendFooterCommand(
std::u16string display_text,
AccessoryAction action) && {
// Calls AppendFooterCommand(...)& since |this| is an lvalue.
return std::move(AppendFooterCommand(std::move(display_text), action));
}
AccessorySheetData::Builder& AccessorySheetData::Builder::AppendFooterCommand(
std::u16string display_text,
AccessoryAction action) & {
accessory_sheet_data_.add_footer_command(
FooterCommand(std::move(display_text), action));
return *this;
}
AccessorySheetData&& AccessorySheetData::Builder::Build() && {
return std::move(accessory_sheet_data_);
}
} // namespace autofill