blob: 40a38a7eadc7db697d8af996569b3ed5ba07ed0e [file] [log] [blame]
// 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_assistant/browser/details.h"
#include <unordered_set>
#include <base/strings/stringprintf.h>
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill_assistant {
constexpr char kSpaceBetweenCardNumAndDate[] = " ";
// static
bool Details::UpdateFromProto(const ShowDetailsProto& proto, Details* details) {
if (!proto.has_details()) {
return false;
}
ShowDetailsProto updated_proto = proto;
// Legacy treatment for old proto fields. Can be removed once the backend
// is updated to set the description_line_1/line_2 fields.
if (updated_proto.details().has_description() &&
!updated_proto.details().has_description_line_2()) {
updated_proto.mutable_details()->set_description_line_2(
updated_proto.details().description());
}
details->SetDetailsProto(updated_proto.details());
details->SetDetailsChangesProto(updated_proto.change_flags());
return true;
}
// static
bool Details::UpdateFromContactDetails(const ShowDetailsProto& proto,
ClientMemory* client_memory,
Details* details) {
std::string contact_details = proto.contact_details();
if (!client_memory->has_selected_address(contact_details)) {
return false;
}
ShowDetailsProto updated_proto = proto;
auto* profile = client_memory->selected_address(contact_details);
auto* details_proto = updated_proto.mutable_details();
// TODO(crbug.com/806868): Get the actual script locale.
std::string app_locale = "en-US";
details_proto->set_title(
l10n_util::GetStringUTF8(IDS_PAYMENTS_CONTACT_DETAILS_LABEL));
details_proto->set_description_line_1(
base::UTF16ToUTF8(profile->GetInfo(autofill::NAME_FULL, app_locale)));
details_proto->set_description_line_2(
base::UTF16ToUTF8(profile->GetInfo(autofill::EMAIL_ADDRESS, app_locale)));
details->SetDetailsProto(updated_proto.details());
details->SetDetailsChangesProto(updated_proto.change_flags());
return true;
}
// static
bool Details::UpdateFromShippingAddress(const ShowDetailsProto& proto,
ClientMemory* client_memory,
Details* details) {
std::string shipping_address = proto.shipping_address();
if (!client_memory->has_selected_address(shipping_address)) {
return false;
}
ShowDetailsProto updated_proto = proto;
auto* profile = client_memory->selected_address(shipping_address);
auto* details_proto = updated_proto.mutable_details();
// TODO(crbug.com/806868): Get the actual script locale.
std::string app_locale = "en-US";
autofill::CountryNames* country_names = autofill::CountryNames::GetInstance();
details_proto->set_title(
l10n_util::GetStringUTF8(IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL));
details_proto->set_description_line_1(
base::UTF16ToUTF8(profile->GetInfo(autofill::NAME_FULL, app_locale)));
details_proto->set_description_line_2(base::StrCat({
base::UTF16ToUTF8(
profile->GetInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, app_locale)),
" ",
base::UTF16ToUTF8(
profile->GetInfo(autofill::ADDRESS_HOME_ZIP, app_locale)),
" ",
base::UTF16ToUTF8(
profile->GetInfo(autofill::ADDRESS_HOME_CITY, app_locale)),
" ",
country_names->GetCountryCode(
profile->GetInfo(autofill::ADDRESS_HOME_COUNTRY, app_locale)),
}));
details->SetDetailsProto(updated_proto.details());
details->SetDetailsChangesProto(updated_proto.change_flags());
return true;
}
bool Details::UpdateFromSelectedCreditCard(const ShowDetailsProto& proto,
ClientMemory* client_memory,
Details* details) {
if (!client_memory->has_selected_card() || !proto.credit_card()) {
return false;
}
ShowDetailsProto updated_proto = proto;
auto* card = client_memory->selected_card();
auto* details_proto = updated_proto.mutable_details();
details_proto->set_title(
l10n_util::GetStringUTF8(IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL));
details_proto->set_description_line_1(
base::StrCat({base::UTF16ToUTF8(card->ObfuscatedLastFourDigits()),
kSpaceBetweenCardNumAndDate,
base::UTF16ToUTF8(card->AbbreviatedExpirationDateForDisplay(
/* with_prefix = */ false))}));
details->SetDetailsProto(updated_proto.details());
details->SetDetailsChangesProto(updated_proto.change_flags());
return true;
}
bool Details::UpdateFromParameters(
const std::map<std::string, std::string>& parameters) {
const auto iter = parameters.find("DETAILS_SHOW_INITIAL");
if (iter != parameters.end() && iter->second.compare("false") == 0) {
return false;
}
// Whenever details are updated from parameters we want to animate missing
// data.
proto_.set_animate_placeholders(true);
proto_.set_show_image_placeholder(true);
if (MaybeUpdateFromDetailsParameters(parameters)) {
return true;
}
// NOTE: The logic below is only needed for backward compatibility.
// Remove once we always pass detail parameters.
bool is_updated = false;
for (const auto& iter : parameters) {
std::string key = iter.first;
if (key == "MOVIES_MOVIE_NAME") {
proto_.set_title(iter.second);
is_updated = true;
continue;
}
if (key == "MOVIES_THEATER_NAME") {
proto_.set_description_line_2(iter.second);
is_updated = true;
continue;
}
if (iter.first.compare("MOVIES_SCREENING_DATETIME") == 0) {
// TODO(crbug.com/806868): Parse the string here and fill
// proto.description_line_1, then get rid of datetime_ in Details.
datetime_ = iter.second;
is_updated = true;
continue;
}
}
return is_updated;
}
bool Details::MaybeUpdateFromDetailsParameters(
const std::map<std::string, std::string>& parameters) {
bool details_updated = false;
for (const auto& iter : parameters) {
std::string key = iter.first;
if (key == "DETAILS_TITLE") {
proto_.set_title(iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_DESCRIPTION_LINE_1") {
proto_.set_description_line_1(iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_DESCRIPTION_LINE_2") {
proto_.set_description_line_2(iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_DESCRIPTION_LINE_3") {
proto_.set_description_line_3(iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_IMAGE_URL") {
proto_.set_image_url(iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_IMAGE_CLICKTHROUGH_URL") {
proto_.mutable_image_clickthrough_data()->set_allow_clickthrough(true);
proto_.mutable_image_clickthrough_data()->set_clickthrough_url(
iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_TOTAL_PRICE_LABEL") {
proto_.set_total_price_label(iter.second);
details_updated = true;
continue;
}
if (key == "DETAILS_TOTAL_PRICE") {
proto_.set_total_price(iter.second);
details_updated = true;
continue;
}
}
return details_updated;
}
void Details::ClearChanges() {
change_flags_.Clear();
}
} // namespace autofill_assistant