chromium/components/autofill/core/browser/data_model/autofill_profile.cc

// Copyright 2013 The Chromium Authors
// 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/data_model/autofill_profile.h"

#include <algorithm>
#include <array>
#include <functional>
#include <map>
#include <memory>
#include <ostream>
#include <ranges>
#include <set>
#include <vector>

#include "base/feature_list.h"
#include "base/hash/sha1.h"
#include "base/i18n/case_conversion.h"
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "base/strings/utf_string_conversions.h"
#include "base/uuid.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_address_util.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/data_model/address.h"
#include "components/autofill/core/browser/data_model/autofill_profile_comparator.h"
#include "components/autofill/core/browser/data_model/autofill_structured_address_utils.h"
#include "components/autofill/core/browser/data_model/contact_info.h"
#include "components/autofill/core/browser/data_model/phone_number.h"
#include "components/autofill/core/browser/field_type_utils.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/geo/address_i18n.h"
#include "components/autofill/core/browser/geo/autofill_country.h"
#include "components/autofill/core/browser/geo/phone_number_i18n.h"
#include "components/autofill/core/browser/geo/state_names.h"
#include "components/autofill/core/browser/metrics/autofill_metrics.h"
#include "components/autofill/core/browser/profile_token_quality.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_l10n_util.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/strings/grit/components_strings.h"
#include "third_party/icu/source/common/unicode/uchar.h"
#include "third_party/icu/source/common/unicode/utypes.h"
#include "third_party/icu/source/i18n/unicode/translit.h"
#include "third_party/libaddressinput/chromium/addressinput_util.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
#include "ui/base/l10n/l10n_util.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "components/autofill/android/main_autofill_jni_headers/AutofillProfile_jni.h"
#endif  // BUILDFLAG(IS_ANDROID)

AddressData;
AddressField;

namespace autofill {

namespace {

// Stores the data types that are relevant for the structured address/name.
const std::array<FieldType, 7> kStructuredDataTypes =;

// Like |AutofillType::GetStorableType()|, but also returns |NAME_FULL| for
// first, middle, and last name field types, and groups phone number types
// similarly.
FieldType GetStorableTypeCollapsingGroupsForPartialType(FieldType type) {}

// Like `GetStorableTypeCollapsingGroupsForPartialType()`, but also similarly
// groups types which include address line 1.
//
// `GetStorableTypeCollapsingGroups()` serves this purpose:
// If `ADDRESS_HOME_STREET_ADDRESS` is an excluded field, we also want to
// exclude `ADDRESS_HOME_LINE1`, because it doesn't add extra relevant
// information. Names and phone numbers also behave like this for the same
// reason. i.e. if `NAME_FIRST` is excluded, we also exclude `NAME_LAST`.
//
// `GetStorableTypeCollapsingGroupsForPartialType()` serves the purpose of
// including `NAME_FULL` in the label candidates, as a last resort, if a partial
// name field is excluded. Similar for phone numbers. For more details, check
// the comment where `GetStorableTypeCollapsingGroupsForPartialType()` is used.
// This does not apply to `ADDRESS_HOME_LINE1`, because if a field is
// `ADDRESS_HOME_STREET_ADDRESS` and we don't want to accidentally include back
// `ADDRESS_HOME_LINE1` in the label candidates.
FieldType GetStorableTypeCollapsingGroups(FieldType type,
                                          bool use_improved_labels_order) {}

// Returns a value that represents specificity/privacy of the given type. This
// is used for prioritizing which data types are shown in inferred labels. For
// example, if the profile is going to fill ADDRESS_HOME_ZIP, it should
// prioritize showing that over ADDRESS_HOME_STATE in the suggestion sublabel.
int SpecificityForType(FieldType type, bool use_improved_labels_order) {}

// Fills `distinguishing_fields` with a list of fields to use when creating
// labels that can help to distinguish between two profiles. Draws fields from
// `suggested_fields` if it is non-NULL; otherwise returns a default list.
// If `suggested_fields` is non-NULL, does not include `excluded_fields` in the
// list. Otherwise, `excluded_fields` is ignored, and should be set to
// an empty list by convention. The resulting list of fields is sorted in
// decreasing order of importance.
void GetFieldsForDistinguishingProfiles(
    const std::vector<FieldType>* suggested_fields,
    FieldTypeSet excluded_fields,
    std::vector<FieldType>* distinguishing_fields,
    bool use_improved_labels_order) {}

#if BUILDFLAG(IS_ANDROID)
// Constructs an AutofillProfile using the provided `existing_profile` as a
// foundation. In case that the `existing_profile` is invalid, an empty profile
// with a unique identifier (GUID) corresponding to the Java profile
// (`jprofile`) is initialized.
AutofillProfile CreateStarterProfile(
    const base::android::JavaParamRef<jobject>& jprofile,
    JNIEnv* env,
    const AutofillProfile* existing_profile) {
  std::string guid = Java_AutofillProfile_getGUID(env, jprofile);
  if (!existing_profile) {
    AutofillProfile::RecordType record_type =
        Java_AutofillProfile_getRecordType(env, jprofile);
    AddressCountryCode country_code =
        AddressCountryCode(Java_AutofillProfile_getCountryCode(env, jprofile));
    AutofillProfile profile = AutofillProfile(record_type, country_code);
    // Only set the guid if CreateStartProfile is called on an existing profile
    // (java guid not empty). Otherwise, keep the generated one.
    // TODO(crbug.com/40282123): `guid` should be always empty when existing
    // profile is not set. CHECK should be added when this condition holds.
    if (!guid.empty()) {
      profile.set_guid(guid);
    }
    return profile;
  }

  CHECK_EQ(existing_profile->guid(), guid);
  return *existing_profile;
}
#endif  // BUILDFLAG(IS_ANDROID)

}  // namespace

AutofillProfile::AutofillProfile(const std::string& guid,
                                 RecordType record_type,
                                 AddressCountryCode country_code)
    :{}

AutofillProfile::AutofillProfile(RecordType record_type,
                                 AddressCountryCode country_code)
    :{}

AutofillProfile::AutofillProfile(AddressCountryCode country_code)
    :{}

AutofillProfile::AutofillProfile(const AutofillProfile& profile)
    :{}

AutofillProfile::~AutofillProfile() = default;

AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {}

#if BUILDFLAG(IS_ANDROID)
base::android::ScopedJavaLocalRef<jobject> AutofillProfile::CreateJavaObject(
    const std::string& app_locale) const {
  JNIEnv* env = base::android::AttachCurrentThread();
  base::android::ScopedJavaLocalRef<jobject> jprofile =
      Java_AutofillProfile_Constructor(
          env, guid(), static_cast<jint>(record_type()), language_code());

  for (FieldType type : GetDatabaseStoredTypesOfAutofillProfile()) {
    auto status = static_cast<jint>(GetVerificationStatus(type));
    // TODO(crbug.com/40278253): Reconcile usage of GetInfo and GetRawInfo
    // below.
    if (type == NAME_FULL) {
      Java_AutofillProfile_setInfo(env, jprofile, static_cast<jint>(type),
                                   GetInfo(type, app_locale), status);
    } else {
      Java_AutofillProfile_setInfo(env, jprofile, static_cast<jint>(type),
                                   GetRawInfo(type), status);
    }
  }
  return jprofile;
}

// static
AutofillProfile AutofillProfile::CreateFromJavaObject(
    const base::android::JavaParamRef<jobject>& jprofile,
    const AutofillProfile* existing_profile,
    const std::string& app_locale) {
  JNIEnv* env = base::android::AttachCurrentThread();
  AutofillProfile profile =
      CreateStarterProfile(jprofile, env, existing_profile);

  std::vector<int> field_types =
      Java_AutofillProfile_getFieldTypes(env, jprofile);

  for (int int_field_type : field_types) {
    FieldType field_type = ToSafeFieldType(int_field_type, NO_SERVER_DATA);
    CHECK(field_type != NO_SERVER_DATA);
    VerificationStatus status =
        Java_AutofillProfile_getInfoStatus(env, jprofile, field_type);
    std::u16string value =
        Java_AutofillProfile_getInfo(env, jprofile, field_type);
    if (value.empty()) {
      continue;
    }
    // TODO(crbug.com/40278253): Reconcile usage of GetInfo and GetRawInfo
    // below.
    if (field_type == NAME_FULL || field_type == ADDRESS_HOME_COUNTRY) {
      profile.SetInfoWithVerificationStatus(field_type, value, app_locale,
                                            status);
    } else {
      profile.SetRawInfoWithVerificationStatus(field_type, value, status);
    }
  }

  profile.set_language_code(
      Java_AutofillProfile_getLanguageCode(env, jprofile));
  profile.FinalizeAfterImport();

  return profile;
}
#endif  // BUILDFLAG(IS_ANDROID)

double AutofillProfile::GetRankingScore(base::Time current_time,
                                        bool use_frecency) const {}

bool AutofillProfile::HasGreaterRankingThan(const AutofillProfile* other,
                                            base::Time comparison_time,
                                            bool use_frecency) const {}

void AutofillProfile::GetMatchingTypes(const std::u16string& text,
                                       const std::string& app_locale,
                                       FieldTypeSet* matching_types) const {}

std::u16string AutofillProfile::GetRawInfo(FieldType type) const {}

void AutofillProfile::SetRawInfoWithVerificationStatus(
    FieldType type,
    const std::u16string& value,
    VerificationStatus status) {}

void AutofillProfile::GetSupportedTypes(FieldTypeSet* supported_types) const {}

FieldType AutofillProfile::GetStorableTypeOf(FieldType type) const {}

bool AutofillProfile::IsEmpty(const std::string& app_locale) const {}

bool AutofillProfile::IsPresentButInvalid(FieldType type) const {}

int AutofillProfile::Compare(const AutofillProfile& profile) const {}

bool AutofillProfile::EqualsForLegacySyncPurposes(
    const AutofillProfile& profile) const {}

bool AutofillProfile::EqualsForUpdatePurposes(
    const AutofillProfile& new_profile) const {}

bool AutofillProfile::operator==(const AutofillProfile& profile) const {}

bool AutofillProfile::IsSubsetOf(const AutofillProfileComparator& comparator,
                                 const AutofillProfile& profile) const {}

bool AutofillProfile::IsSubsetOfForFieldSet(
    const AutofillProfileComparator& comparator,
    const AutofillProfile& profile,
    const FieldTypeSet& types) const {}

bool AutofillProfile::IsStrictSupersetOf(
    const AutofillProfileComparator& comparator,
    const AutofillProfile& profile) const {}

AddressCountryCode AutofillProfile::GetAddressCountryCode() const {}

bool AutofillProfile::IsAccountProfile() const {}

void AutofillProfile::OverwriteDataFromForLegacySync(
    const AutofillProfile& profile) {}

bool AutofillProfile::MergeDataFrom(const AutofillProfile& profile,
                                    const std::string& app_locale) {}

void AutofillProfile::MergeFormGroupTokenQuality(
    const FormGroup& merged_group,
    const AutofillProfile& other_profile) {}

// static
void AutofillProfile::CreateDifferentiatingLabels(
    const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
        profiles,
    const std::string& app_locale,
    std::vector<std::u16string>* labels) {}

// static
void AutofillProfile::CreateInferredLabels(
    const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
        profiles,
    const std::optional<FieldTypeSet> suggested_fields,
    std::optional<FieldType> triggering_field_type,
    FieldTypeSet excluded_fields,
    size_t minimal_fields_shown,
    const std::string& app_locale,
    std::vector<std::u16string>* labels,
    bool use_improved_labels_order) {}

std::u16string AutofillProfile::ConstructInferredLabel(
    base::span<const FieldType> included_fields,
    size_t num_fields_to_use,
    const std::string& app_locale) const {}

void AutofillProfile::RecordAndLogUse() {}

void AutofillProfile::LogVerificationStatuses() {}

VerificationStatus AutofillProfile::GetVerificationStatusImpl(
    const FieldType type) const {}

std::u16string AutofillProfile::GetInfoImpl(
    const AutofillType& type,
    const std::string& app_locale) const {}

bool AutofillProfile::SetInfoWithVerificationStatusImpl(
    const AutofillType& type,
    const std::u16string& value,
    const std::string& app_locale,
    VerificationStatus status) {}

// static
void AutofillProfile::CreateInferredLabelsHelper(
    const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
        profiles,
    const std::list<size_t>& indices,
    const std::vector<FieldType>& field_types,
    size_t num_fields_to_include,
    const std::string& app_locale,
    std::vector<std::u16string>* labels) {}

const FormGroup* AutofillProfile::FormGroupForType(FieldType type) const {}

FormGroup* AutofillProfile::MutableFormGroupForType(FieldType type) {}

bool AutofillProfile::EqualsSansGuid(const AutofillProfile& profile) const {}

std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {}

bool AutofillProfile::FinalizeAfterImport() {}

bool AutofillProfile::HasStructuredData() const {}

AutofillProfile AutofillProfile::ConvertToAccountProfile() const {}

FieldTypeSet AutofillProfile::FindInaccessibleProfileValues() const {}

void AutofillProfile::ClearFields(const FieldTypeSet& fields) {}

AutofillType AutofillProfile::GetFillingType(AutofillType field_type) const {}

}  // namespace autofill