blob: ae134a57a5865cc1160998ff1146305ff19a10ac [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/android/ui_controller_android_utils.h"
#include <utility>
#include <vector>
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/base64.h"
#include "base/containers/flat_map.h"
#include "base/notreached.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill_assistant/android/jni_headers/AssistantChip_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantColor_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantDateTime_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantDialogButton_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantDimension_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantDrawable_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantInfoPopup_jni.h"
#include "components/autofill_assistant/android/jni_headers/AssistantValue_jni.h"
#include "components/autofill_assistant/android/jni_headers/AutofillAssistantDependencyInjector_jni.h"
#include "components/autofill_assistant/android/jni_headers_public/AssistantAutofillCreditCard_jni.h"
#include "components/autofill_assistant/android/jni_headers_public/AssistantAutofillProfile_jni.h"
#include "components/autofill_assistant/browser/android/client_android.h"
#include "components/autofill_assistant/browser/android/dependencies_android.h"
#include "components/autofill_assistant/browser/generic_ui_java_generated_enums.h"
#include "components/autofill_assistant/browser/service/service.h"
#include "components/autofill_assistant/browser/service/service_request_sender.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/android/gurl_android.h"
namespace autofill_assistant {
namespace ui_controller_android_utils {
namespace {
using ::base::android::ConvertJavaStringToUTF16;
using ::base::android::ConvertJavaStringToUTF8;
using ::base::android::ConvertUTF16ToJavaString;
using ::base::android::ConvertUTF8ToJavaString;
using ::base::android::JavaRef;
DrawableIcon MapDrawableIcon(DrawableProto::Icon icon) {
switch (icon) {
case DrawableProto::DRAWABLE_ICON_UNDEFINED:
return DrawableIcon::DRAWABLE_ICON_UNDEFINED;
case DrawableProto::PROGRESSBAR_DEFAULT_INITIAL_STEP:
return DrawableIcon::PROGRESSBAR_DEFAULT_INITIAL_STEP;
case DrawableProto::PROGRESSBAR_DEFAULT_DATA_COLLECTION:
return DrawableIcon::PROGRESSBAR_DEFAULT_DATA_COLLECTION;
case DrawableProto::PROGRESSBAR_DEFAULT_PAYMENT:
return DrawableIcon::PROGRESSBAR_DEFAULT_PAYMENT;
case DrawableProto::PROGRESSBAR_DEFAULT_FINAL_STEP:
return DrawableIcon::PROGRESSBAR_DEFAULT_FINAL_STEP;
case DrawableProto::SITTING_PERSON:
return DrawableIcon::SITTING_PERSON;
case DrawableProto::TICKET_STUB:
return DrawableIcon::TICKET_STUB;
case DrawableProto::SHOPPING_BASKET:
return DrawableIcon::SHOPPING_BASKET;
case DrawableProto::FAST_FOOD:
return DrawableIcon::FAST_FOOD;
case DrawableProto::LOCAL_DINING:
return DrawableIcon::LOCAL_DINING;
case DrawableProto::COGWHEEL:
return DrawableIcon::COGWHEEL;
case DrawableProto::KEY:
return DrawableIcon::KEY;
case DrawableProto::CAR:
return DrawableIcon::CAR;
case DrawableProto::GROCERY:
return DrawableIcon::GROCERY;
case DrawableProto::VISIBILITY_ON:
return DrawableIcon::VISIBILITY_ON;
case DrawableProto::VISIBILITY_OFF:
return DrawableIcon::VISIBILITY_OFF;
}
}
void MaybeSetInfo(autofill::AutofillProfile* profile,
autofill::ServerFieldType type,
const JavaRef<jstring>& value,
const std::string& locale) {
if (value) {
profile->SetInfo(type, ConvertJavaStringToUTF16(value), locale);
}
}
void MaybeSetRawInfo(autofill::AutofillProfile* profile,
autofill::ServerFieldType type,
const JavaRef<jstring>& value) {
if (value) {
profile->SetRawInfo(type, ConvertJavaStringToUTF16(value));
}
}
} // namespace
base::android::ScopedJavaLocalRef<jobject> GetJavaColor(
JNIEnv* env,
const std::string& color_string) {
if (!Java_AssistantColor_isValidColorString(
env, base::android::ConvertUTF8ToJavaString(env, color_string))) {
if (!color_string.empty()) {
VLOG(1) << "Encountered invalid color string: " << color_string;
}
return nullptr;
}
return Java_AssistantColor_createFromString(
env, base::android::ConvertUTF8ToJavaString(env, color_string));
}
base::android::ScopedJavaLocalRef<jobject> GetJavaColor(
JNIEnv* env,
const JavaRef<jobject>& jcontext,
const ColorProto& proto) {
switch (proto.color_case()) {
case ColorProto::kResourceIdentifier:
if (!Java_AssistantColor_isValidResourceIdentifier(
env, jcontext,
base::android::ConvertUTF8ToJavaString(
env, proto.resource_identifier()))) {
VLOG(1) << "Encountered invalid color resource identifier: "
<< proto.resource_identifier();
return nullptr;
}
return Java_AssistantColor_createFromResource(
env, jcontext,
base::android::ConvertUTF8ToJavaString(env,
proto.resource_identifier()));
case ColorProto::kParseableColor:
return GetJavaColor(env, proto.parseable_color());
case ColorProto::COLOR_NOT_SET:
return nullptr;
}
}
absl::optional<int> GetPixelSize(JNIEnv* env,
const JavaRef<jobject>& jcontext,
const ClientDimensionProto& proto) {
switch (proto.size_case()) {
case ClientDimensionProto::kDp:
return Java_AssistantDimension_getPixelSizeDp(env, jcontext, proto.dp());
case ClientDimensionProto::kWidthFactor:
return Java_AssistantDimension_getPixelSizeWidthFactor(
env, jcontext, proto.width_factor());
case ClientDimensionProto::kHeightFactor:
return Java_AssistantDimension_getPixelSizeHeightFactor(
env, jcontext, proto.height_factor());
case ClientDimensionProto::kSizeInPixel:
return proto.size_in_pixel();
case ClientDimensionProto::SIZE_NOT_SET:
return absl::nullopt;
}
}
int GetPixelSizeOrDefault(JNIEnv* env,
const JavaRef<jobject>& jcontext,
const ClientDimensionProto& proto,
int default_value) {
auto size = GetPixelSize(env, jcontext, proto);
if (size) {
return *size;
}
return default_value;
}
base::android::ScopedJavaLocalRef<jobject> CreateJavaDrawable(
JNIEnv* env,
const JavaRef<jobject>& jcontext,
const DependenciesAndroid& dependencies,
const DrawableProto& proto,
const UserModel* user_model) {
switch (proto.drawable_case()) {
case DrawableProto::kResourceIdentifier:
if (!Java_AssistantDrawable_isValidDrawableResource(
env, jcontext,
base::android::ConvertUTF8ToJavaString(
env, proto.resource_identifier()))) {
VLOG(1) << "Encountered invalid drawable resource identifier: "
<< proto.resource_identifier();
return nullptr;
}
return Java_AssistantDrawable_createFromResource(
env, base::android::ConvertUTF8ToJavaString(
env, proto.resource_identifier()));
case DrawableProto::kBitmap: {
int width_pixels = ui_controller_android_utils::GetPixelSizeOrDefault(
env, jcontext, proto.bitmap().width(), 0);
int height_pixels = ui_controller_android_utils::GetPixelSizeOrDefault(
env, jcontext, proto.bitmap().height(), 0);
return Java_AssistantDrawable_createFromUrl(
env, dependencies.CreateImageFetcher(),
base::android::ConvertUTF8ToJavaString(env, proto.bitmap().url()),
width_pixels, height_pixels);
}
case DrawableProto::kShape: {
switch (proto.shape().shape_case()) {
case ShapeDrawableProto::kRectangle: {
auto jbackground_color = ui_controller_android_utils::GetJavaColor(
env, jcontext, proto.shape().background_color());
auto jstroke_color = ui_controller_android_utils::GetJavaColor(
env, jcontext, proto.shape().stroke_color());
int stroke_width_pixels =
ui_controller_android_utils::GetPixelSizeOrDefault(
env, jcontext, proto.shape().stroke_width(), 0);
int corner_radius_pixels =
ui_controller_android_utils::GetPixelSizeOrDefault(
env, jcontext, proto.shape().rectangle().corner_radius(), 0);
return Java_AssistantDrawable_createRectangleShape(
env, jbackground_color, jstroke_color, stroke_width_pixels,
corner_radius_pixels);
}
case ShapeDrawableProto::SHAPE_NOT_SET:
return nullptr;
}
}
case DrawableProto::kIcon: {
return Java_AssistantDrawable_createFromIcon(
env, static_cast<int>(MapDrawableIcon(proto.icon())));
}
case DrawableProto::kImageData: {
return Java_AssistantDrawable_createFromBase64(
env, base::android::ToJavaByteArray(env, proto.image_data()));
}
case DrawableProto::kImageDataBase64: {
std::string image_data;
if (!base::Base64Decode(proto.image_data_base64(), &image_data)) {
VLOG(1) << "Invalid Base64 image data.";
return nullptr;
}
return Java_AssistantDrawable_createFromBase64(
env, base::android::ToJavaByteArray(env, image_data));
}
case DrawableProto::kFavicon: {
if (!user_model) {
VLOG(1) << "User model missing while trying to create a favicon.";
return nullptr;
}
int diameter_size_in_pixel =
ui_controller_android_utils::GetPixelSizeOrDefault(
env, jcontext, proto.favicon().diameter_size(), 0);
GURL url = proto.favicon().has_website_url()
? GURL(proto.favicon().website_url())
: user_model->GetCurrentURL();
return Java_AssistantDrawable_createFromFavicon(
env, dependencies.CreateIconBridge(),
url::GURLAndroid::FromNativeGURL(env, url), diameter_size_in_pixel,
proto.favicon().force_monogram());
}
case DrawableProto::DRAWABLE_NOT_SET:
return nullptr;
}
}
base::android::ScopedJavaLocalRef<jobject> ToJavaValue(
JNIEnv* env,
const ValueProto& proto) {
switch (proto.kind_case()) {
case ValueProto::kStrings: {
std::vector<std::string> strings;
strings.reserve(proto.strings().values_size());
for (const auto& string : proto.strings().values()) {
strings.push_back(string);
}
return Java_AssistantValue_createForStrings(
env, base::android::ToJavaArrayOfStrings(env, strings));
}
case ValueProto::kBooleans: {
auto booleans = std::make_unique<bool[]>(proto.booleans().values_size());
for (int i = 0; i < proto.booleans().values_size(); ++i) {
booleans[i] = proto.booleans().values()[i];
}
return Java_AssistantValue_createForBooleans(
env, base::android::ToJavaBooleanArray(
env, booleans.get(), proto.booleans().values_size()));
}
case ValueProto::kInts: {
auto ints = std::make_unique<int[]>(proto.ints().values_size());
for (int i = 0; i < proto.ints().values_size(); ++i) {
ints[i] = proto.ints().values()[i];
}
return Java_AssistantValue_createForIntegers(
env, base::android::ToJavaIntArray(env, ints.get(),
proto.ints().values_size()));
}
case ValueProto::kCreditCards:
case ValueProto::kProfiles:
case ValueProto::kLoginOptions:
case ValueProto::kCreditCardResponse:
case ValueProto::kServerPayload:
case ValueProto::kUserActions:
// Unused.
NOTREACHED();
return nullptr;
case ValueProto::kDates: {
auto jlist = Java_AssistantValue_createDateTimeList(env);
for (const auto& value : proto.dates().values()) {
Java_AssistantValue_addDateTimeToList(
env, jlist,
Java_AssistantDateTime_Constructor(
env, static_cast<int>(value.year()), value.month(), value.day(),
0, 0, 0));
}
return Java_AssistantValue_createForDateTimes(env, jlist);
}
case ValueProto::KIND_NOT_SET:
return Java_AssistantValue_create(env);
}
}
ValueProto ToNativeValue(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jvalue) {
ValueProto proto;
if (!jvalue) {
return proto;
}
auto jints = Java_AssistantValue_getIntegers(env, jvalue);
if (jints) {
auto* mutable_ints = proto.mutable_ints();
std::vector<int> ints;
base::android::JavaIntArrayToIntVector(env, jints, &ints);
for (int i : ints) {
mutable_ints->add_values(i);
}
return proto;
}
auto jbooleans = Java_AssistantValue_getBooleans(env, jvalue);
if (jbooleans) {
auto* mutable_booleans = proto.mutable_booleans();
std::vector<bool> booleans;
base::android::JavaBooleanArrayToBoolVector(env, jbooleans, &booleans);
for (auto b : booleans) {
mutable_booleans->add_values(b);
}
return proto;
}
auto jstrings = Java_AssistantValue_getStrings(env, jvalue);
if (jstrings) {
auto* mutable_strings = proto.mutable_strings();
std::vector<std::string> strings;
base::android::AppendJavaStringArrayToStringVector(env, jstrings, &strings);
for (const auto& string : strings) {
mutable_strings->add_values(string);
}
return proto;
}
auto jdatetimes = Java_AssistantValue_getDateTimes(env, jvalue);
if (jdatetimes) {
auto* mutable_dates = proto.mutable_dates();
for (int i = 0; i < Java_AssistantValue_getListSize(env, jdatetimes); ++i) {
auto jvalue = Java_AssistantValue_getListAt(env, jdatetimes, i);
DateProto date;
date.set_year(Java_AssistantDateTime_getYear(env, jvalue));
date.set_month(Java_AssistantDateTime_getMonth(env, jvalue));
date.set_day(Java_AssistantDateTime_getDay(env, jvalue));
*mutable_dates->add_values() = date;
}
return proto;
}
return proto;
}
base::android::ScopedJavaLocalRef<jobject> CreateJavaDialogButton(
JNIEnv* env,
const InfoPopupProto_DialogButton& button_proto,
const JavaRef<jobject>& jinfo_page_util) {
base::android::ScopedJavaLocalRef<jstring> jurl = nullptr;
switch (button_proto.click_action_case()) {
case InfoPopupProto::DialogButton::kOpenUrlInCct:
jurl = base::android::ConvertUTF8ToJavaString(
env, button_proto.open_url_in_cct().url());
break;
case InfoPopupProto::DialogButton::kCloseDialog:
break;
case InfoPopupProto::DialogButton::CLICK_ACTION_NOT_SET:
NOTREACHED();
break;
}
return Java_AssistantDialogButton_Constructor(
env, jinfo_page_util,
base::android::ConvertUTF8ToJavaString(env, button_proto.label()), jurl);
}
base::android::ScopedJavaLocalRef<jobject> CreateJavaInfoPopup(
JNIEnv* env,
const InfoPopupProto& info_popup_proto,
const JavaRef<jobject>& jinfo_page_util,
const std::string& close_display_str) {
base::android::ScopedJavaLocalRef<jobject> jpositive_button = nullptr;
base::android::ScopedJavaLocalRef<jobject> jnegative_button = nullptr;
base::android::ScopedJavaLocalRef<jobject> jneutral_button = nullptr;
if (info_popup_proto.has_positive_button() ||
info_popup_proto.has_negative_button() ||
info_popup_proto.has_neutral_button()) {
if (info_popup_proto.has_positive_button()) {
jpositive_button = CreateJavaDialogButton(
env, info_popup_proto.positive_button(), jinfo_page_util);
}
if (info_popup_proto.has_negative_button()) {
jnegative_button = CreateJavaDialogButton(
env, info_popup_proto.negative_button(), jinfo_page_util);
}
if (info_popup_proto.has_neutral_button()) {
jneutral_button = CreateJavaDialogButton(
env, info_popup_proto.neutral_button(), jinfo_page_util);
}
} else {
// If no button is set in the proto, we add a Close button
jpositive_button = Java_AssistantDialogButton_Constructor(
env, jinfo_page_util,
base::android::ConvertUTF8ToJavaString(env, close_display_str),
nullptr);
}
return Java_AssistantInfoPopup_Constructor(
env,
base::android::ConvertUTF8ToJavaString(env, info_popup_proto.title()),
base::android::ConvertUTF8ToJavaString(env, info_popup_proto.text()),
jpositive_button, jnegative_button, jneutral_button);
}
void ShowJavaInfoPopup(JNIEnv* env,
const JavaRef<jobject>& jinfo_popup,
const JavaRef<jobject>& jcontext) {
Java_AssistantInfoPopup_show(env, jinfo_popup, jcontext);
}
std::string SafeConvertJavaStringToNative(
JNIEnv* env,
const base::android::JavaRef<jstring>& jstring) {
std::string native_string;
if (jstring) {
native_string = base::android::ConvertJavaStringToUTF8(env, jstring);
}
return native_string;
}
base::android::ScopedJavaLocalRef<jstring> ConvertNativeOptionalStringToJava(
JNIEnv* env,
const absl::optional<std::string> optional_string) {
if (!optional_string.has_value()) {
return nullptr;
}
return base::android::ConvertUTF8ToJavaString(env, *optional_string);
}
BottomSheetState ToNativeBottomSheetState(int state) {
switch (state) {
case 1:
return BottomSheetState::COLLAPSED;
case 2:
case 3:
return BottomSheetState::EXPANDED;
default:
return BottomSheetState::UNDEFINED;
}
}
int ToJavaBottomSheetState(BottomSheetState state) {
switch (state) {
case BottomSheetState::COLLAPSED:
return 1;
case BottomSheetState::UNDEFINED:
// The current assumption is that Autobot always starts with the bottom
// sheet expanded.
case BottomSheetState::EXPANDED:
return 2;
default:
return -1;
}
}
base::android::ScopedJavaLocalRef<jobject> CreateJavaAssistantChip(
JNIEnv* env,
const ChipProto& chip) {
switch (chip.type()) {
default: // Other chip types are not supported.
return nullptr;
case HIGHLIGHTED_ACTION:
case DONE_ACTION:
return Java_AssistantChip_createHighlightedAssistantChip(
env, chip.icon(),
base::android::ConvertUTF8ToJavaString(env, chip.text()),
/* disabled = */ false, chip.sticky(), /* visible = */ true,
chip.has_content_description()
? base::android::ConvertUTF8ToJavaString(
env, chip.content_description())
: nullptr,
/* optionalIdentifier = */
base::android::ConvertUTF8ToJavaString(env, std::string()));
case NORMAL_ACTION:
case CANCEL_ACTION:
case CLOSE_ACTION:
case FEEDBACK_ACTION:
return Java_AssistantChip_createHairlineAssistantChip(
env, chip.icon(),
base::android::ConvertUTF8ToJavaString(env, chip.text()),
/* disabled = */ false, chip.sticky(), /* visible = */ true,
chip.has_content_description()
? base::android::ConvertUTF8ToJavaString(
env, chip.content_description())
: nullptr,
/* optionalIdentifier= */
base::android::ConvertUTF8ToJavaString(env, std::string()));
}
}
base::android::ScopedJavaLocalRef<jobject> CreateJavaAssistantChipList(
JNIEnv* env,
const std::vector<ChipProto>& chips) {
auto jlist = Java_AssistantChip_createChipList(env);
for (const auto& chip : chips) {
auto jchip = CreateJavaAssistantChip(env, chip);
if (!jchip) {
return nullptr;
}
Java_AssistantChip_addChipToList(env, jlist, jchip);
}
return jlist;
}
base::flat_map<std::string, std::string> CreateStringMapFromJava(
JNIEnv* env,
const JavaRef<jobjectArray>& names,
const JavaRef<jobjectArray>& values) {
std::vector<std::string> names_vector;
base::android::AppendJavaStringArrayToStringVector(env, names, &names_vector);
std::vector<std::string> values_vector;
base::android::AppendJavaStringArrayToStringVector(env, values,
&values_vector);
std::vector<std::pair<std::string, std::string>> result;
DCHECK_EQ(names_vector.size(), values_vector.size());
for (size_t i = 0; i < names_vector.size(); ++i) {
result.emplace_back(names_vector[i], values_vector[i]);
}
return base::flat_map<std::string, std::string>(std::move(result));
}
std::unique_ptr<TriggerContext> CreateTriggerContext(
JNIEnv* env,
content::WebContents* web_contents,
const JavaRef<jstring>& jexperiment_ids,
const JavaRef<jobjectArray>& jparameter_names,
const JavaRef<jobjectArray>& jparameter_values,
const JavaRef<jobjectArray>& jdevice_only_parameter_names,
const JavaRef<jobjectArray>& jdevice_only_parameter_values,
jboolean onboarding_shown,
jboolean is_direct_action,
const JavaRef<jstring>& jinitial_url,
const bool is_custom_tab) {
auto script_parameters = std::make_unique<ScriptParameters>(
CreateStringMapFromJava(env, jparameter_names, jparameter_values));
script_parameters->UpdateDeviceOnlyParameters(CreateStringMapFromJava(
env, jdevice_only_parameter_names, jdevice_only_parameter_values));
return std::make_unique<TriggerContext>(
std::move(script_parameters),
SafeConvertJavaStringToNative(env, jexperiment_ids), is_custom_tab,
onboarding_shown, is_direct_action,
SafeConvertJavaStringToNative(env, jinitial_url),
/* is_in_chrome_triggered = */ false,
/* is_externally_triggered = */ false);
}
std::unique_ptr<Service> GetServiceToInject(JNIEnv* env,
ClientAndroid* client_android) {
jlong jtest_service_to_inject =
Java_AutofillAssistantDependencyInjector_getServiceToInject(
env, reinterpret_cast<intptr_t>(client_android));
std::unique_ptr<Service> test_service = nullptr;
if (jtest_service_to_inject) {
test_service.reset(static_cast<Service*>(
reinterpret_cast<void*>(jtest_service_to_inject)));
}
return test_service;
}
std::unique_ptr<ServiceRequestSender> GetServiceRequestSenderToInject(
JNIEnv* env) {
jlong jtest_service_request_sender_to_inject =
Java_AutofillAssistantDependencyInjector_getServiceRequestSenderToInject(
env);
std::unique_ptr<ServiceRequestSender> test_service_request_sender;
if (jtest_service_request_sender_to_inject) {
test_service_request_sender.reset(static_cast<ServiceRequestSender*>(
reinterpret_cast<void*>(jtest_service_request_sender_to_inject)));
}
return test_service_request_sender;
}
std::unique_ptr<AutofillAssistantTtsController> GetTtsControllerToInject(
JNIEnv* env) {
jlong jtest_tts_controller_to_inject =
Java_AutofillAssistantDependencyInjector_getTtsControllerToInject(env);
std::unique_ptr<AutofillAssistantTtsController> test_tts_controller;
if (jtest_tts_controller_to_inject) {
test_tts_controller.reset(static_cast<AutofillAssistantTtsController*>(
reinterpret_cast<void*>(jtest_tts_controller_to_inject)));
}
return test_tts_controller;
}
base::android::ScopedJavaLocalRef<jobject> CreateAssistantAutofillProfile(
JNIEnv* env,
const autofill::AutofillProfile& profile,
const std::string& locale) {
return Java_AssistantAutofillProfile_Constructor(
env, ConvertUTF8ToJavaString(env, profile.guid()),
ConvertUTF8ToJavaString(env, profile.origin()),
profile.record_type() == autofill::AutofillProfile::LOCAL_PROFILE,
ConvertUTF16ToJavaString(
env, profile.GetInfo(autofill::NAME_HONORIFIC_PREFIX, locale)),
ConvertUTF16ToJavaString(env,
profile.GetInfo(autofill::NAME_FULL, locale)),
ConvertUTF16ToJavaString(env, profile.GetRawInfo(autofill::COMPANY_NAME)),
ConvertUTF16ToJavaString(
env, profile.GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS)),
ConvertUTF16ToJavaString(
env, profile.GetRawInfo(autofill::ADDRESS_HOME_STATE)),
ConvertUTF16ToJavaString(env,
profile.GetRawInfo(autofill::ADDRESS_HOME_CITY)),
ConvertUTF16ToJavaString(
env, profile.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY)),
ConvertUTF16ToJavaString(env,
profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP)),
ConvertUTF16ToJavaString(
env, profile.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE)),
ConvertUTF16ToJavaString(
env, profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)),
ConvertUTF16ToJavaString(
env, profile.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER)),
ConvertUTF16ToJavaString(env,
profile.GetRawInfo(autofill::EMAIL_ADDRESS)),
ConvertUTF8ToJavaString(env, profile.language_code()));
}
void PopulateAutofillProfileFromJava(
const base::android::JavaParamRef<jobject>& jprofile,
JNIEnv* env,
autofill::AutofillProfile* profile,
const std::string& locale) {
// Only set the guid if it is an existing profile (Java guid not empty).
// Otherwise, keep the generated one.
std::string guid = ConvertJavaStringToUTF8(
Java_AssistantAutofillProfile_getGUID(env, jprofile));
if (!guid.empty()) {
profile->set_guid(guid);
}
profile->set_origin(ConvertJavaStringToUTF8(
Java_AssistantAutofillProfile_getOrigin(env, jprofile)));
MaybeSetInfo(profile, autofill::NAME_FULL,
Java_AssistantAutofillProfile_getFullName(env, jprofile),
locale);
MaybeSetRawInfo(
profile, autofill::NAME_HONORIFIC_PREFIX,
Java_AssistantAutofillProfile_getHonorificPrefix(env, jprofile));
MaybeSetRawInfo(profile, autofill::COMPANY_NAME,
Java_AssistantAutofillProfile_getCompanyName(env, jprofile));
MaybeSetRawInfo(
profile, autofill::ADDRESS_HOME_STREET_ADDRESS,
Java_AssistantAutofillProfile_getStreetAddress(env, jprofile));
MaybeSetRawInfo(profile, autofill::ADDRESS_HOME_STATE,
Java_AssistantAutofillProfile_getRegion(env, jprofile));
MaybeSetRawInfo(profile, autofill::ADDRESS_HOME_CITY,
Java_AssistantAutofillProfile_getLocality(env, jprofile));
MaybeSetRawInfo(
profile, autofill::ADDRESS_HOME_DEPENDENT_LOCALITY,
Java_AssistantAutofillProfile_getDependentLocality(env, jprofile));
MaybeSetRawInfo(profile, autofill::ADDRESS_HOME_ZIP,
Java_AssistantAutofillProfile_getPostalCode(env, jprofile));
MaybeSetRawInfo(profile, autofill::ADDRESS_HOME_SORTING_CODE,
Java_AssistantAutofillProfile_getSortingCode(env, jprofile));
MaybeSetInfo(profile, autofill::ADDRESS_HOME_COUNTRY,
Java_AssistantAutofillProfile_getCountryCode(env, jprofile),
locale);
MaybeSetRawInfo(profile, autofill::PHONE_HOME_WHOLE_NUMBER,
Java_AssistantAutofillProfile_getPhoneNumber(env, jprofile));
MaybeSetRawInfo(profile, autofill::EMAIL_ADDRESS,
Java_AssistantAutofillProfile_getEmailAddress(env, jprofile));
profile->set_language_code(ConvertJavaStringToUTF8(
Java_AssistantAutofillProfile_getLanguageCode(env, jprofile)));
profile->FinalizeAfterImport();
}
base::android::ScopedJavaLocalRef<jobject> CreateAssistantAutofillCreditCard(
JNIEnv* env,
const autofill::CreditCard& credit_card,
const std::string& locale) {
const autofill::data_util::PaymentRequestData& payment_request_data =
autofill::data_util::GetPaymentRequestData(credit_card.network());
return Java_AssistantAutofillCreditCard_Constructor(
env, ConvertUTF8ToJavaString(env, credit_card.guid()),
ConvertUTF8ToJavaString(env, credit_card.origin()),
credit_card.record_type() == autofill::CreditCard::LOCAL_CARD,
credit_card.record_type() == autofill::CreditCard::FULL_SERVER_CARD,
ConvertUTF16ToJavaString(
env, credit_card.GetRawInfo(autofill::CREDIT_CARD_NAME_FULL)),
ConvertUTF16ToJavaString(
env, credit_card.GetRawInfo(autofill::CREDIT_CARD_NUMBER)),
ConvertUTF16ToJavaString(env, credit_card.NetworkAndLastFourDigits()),
ConvertUTF16ToJavaString(
env, credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH)),
ConvertUTF16ToJavaString(
env, credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)),
ConvertUTF8ToJavaString(env,
payment_request_data.basic_card_issuer_network),
Java_AssistantAutofillCreditCard_getIssuerIconDrawableId(
env, ConvertUTF8ToJavaString(
env, credit_card.CardIconStringForAutofillSuggestion())),
ConvertUTF8ToJavaString(env, credit_card.billing_address_id()),
ConvertUTF8ToJavaString(env, credit_card.server_id()),
credit_card.instrument_id(),
ConvertUTF16ToJavaString(env, credit_card.nickname()),
url::GURLAndroid::FromNativeGURL(env, credit_card.card_art_url()),
static_cast<jint>(credit_card.virtual_card_enrollment_state()),
ConvertUTF16ToJavaString(env, credit_card.product_description()));
}
void PopulateAutofillCreditCardFromJava(
const base::android::JavaParamRef<jobject>& jcredit_card,
JNIEnv* env,
autofill::CreditCard* credit_card,
const std::string& locale) {
// Only set the guid if it is an existing card (java guid not empty).
// Otherwise, keep the generated one.
std::string guid = ConvertJavaStringToUTF8(
Java_AssistantAutofillCreditCard_getGUID(env, jcredit_card));
if (!guid.empty()) {
credit_card->set_guid(guid);
}
if (Java_AssistantAutofillCreditCard_getIsLocal(env, jcredit_card)) {
credit_card->set_record_type(autofill::CreditCard::LOCAL_CARD);
} else {
if (Java_AssistantAutofillCreditCard_getIsCached(env, jcredit_card)) {
credit_card->set_record_type(autofill::CreditCard::FULL_SERVER_CARD);
} else {
credit_card->set_record_type(autofill::CreditCard::MASKED_SERVER_CARD);
credit_card->SetNetworkForMaskedCard(
autofill::data_util::GetIssuerNetworkForBasicCardIssuerNetwork(
ConvertJavaStringToUTF8(
env,
Java_AssistantAutofillCreditCard_getBasicCardIssuerNetwork(
env, jcredit_card))));
}
}
credit_card->set_origin(ConvertJavaStringToUTF8(
Java_AssistantAutofillCreditCard_getOrigin(env, jcredit_card)));
credit_card->SetRawInfo(
autofill::CREDIT_CARD_NAME_FULL,
ConvertJavaStringToUTF16(
Java_AssistantAutofillCreditCard_getName(env, jcredit_card)));
credit_card->SetRawInfo(
autofill::CREDIT_CARD_NUMBER,
ConvertJavaStringToUTF16(
Java_AssistantAutofillCreditCard_getNumber(env, jcredit_card)));
credit_card->SetRawInfo(
autofill::CREDIT_CARD_EXP_MONTH,
ConvertJavaStringToUTF16(
Java_AssistantAutofillCreditCard_getMonth(env, jcredit_card)));
credit_card->SetRawInfo(
autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR,
ConvertJavaStringToUTF16(
Java_AssistantAutofillCreditCard_getYear(env, jcredit_card)));
credit_card->set_billing_address_id(ConvertJavaStringToUTF8(
Java_AssistantAutofillCreditCard_getBillingAddressId(env, jcredit_card)));
credit_card->set_server_id(ConvertJavaStringToUTF8(
Java_AssistantAutofillCreditCard_getServerId(env, jcredit_card)));
credit_card->set_instrument_id(
Java_AssistantAutofillCreditCard_getInstrumentId(env, jcredit_card));
credit_card->SetNickname(ConvertJavaStringToUTF16(
Java_AssistantAutofillCreditCard_getNickname(env, jcredit_card)));
base::android::ScopedJavaLocalRef<jobject> jcard_art_url =
Java_AssistantAutofillCreditCard_getCardArtUrl(env, jcredit_card);
if (!jcard_art_url.is_null()) {
credit_card->set_card_art_url(
*url::GURLAndroid::ToNativeGURL(env, jcard_art_url));
}
credit_card->set_virtual_card_enrollment_state(
static_cast<autofill::CreditCard::VirtualCardEnrollmentState>(
Java_AssistantAutofillCreditCard_getVirtualCardEnrollmentState(
env, jcredit_card)));
credit_card->set_product_description(ConvertJavaStringToUTF16(
Java_AssistantAutofillCreditCard_getProductDescription(env,
jcredit_card)));
}
} // namespace ui_controller_android_utils
} // namespace autofill_assistant