Home | History | Annotate | Download | only in browser
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/autofill/core/browser/autofill_profile.h"
      6 
      7 #include <algorithm>
      8 #include <functional>
      9 #include <map>
     10 #include <ostream>
     11 #include <set>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/guid.h"
     15 #include "base/logging.h"
     16 #include "base/strings/string_util.h"
     17 #include "base/strings/utf_string_conversions.h"
     18 #include "components/autofill/core/browser/address.h"
     19 #include "components/autofill/core/browser/autofill_country.h"
     20 #include "components/autofill/core/browser/autofill_field.h"
     21 #include "components/autofill/core/browser/autofill_type.h"
     22 #include "components/autofill/core/browser/contact_info.h"
     23 #include "components/autofill/core/browser/phone_number.h"
     24 #include "components/autofill/core/browser/phone_number_i18n.h"
     25 #include "components/autofill/core/browser/validation.h"
     26 #include "components/autofill/core/common/form_field_data.h"
     27 #include "grit/component_strings.h"
     28 #include "ui/base/l10n/l10n_util.h"
     29 
     30 namespace autofill {
     31 namespace {
     32 
     33 // Like |AutofillType::GetStorableType()|, but also returns |NAME_FULL| for
     34 // first, middle, and last name field types.
     35 ServerFieldType GetStorableTypeCollapsingNames(ServerFieldType type) {
     36   ServerFieldType storable_type = AutofillType(type).GetStorableType();
     37   if (AutofillType(storable_type).group() == NAME)
     38     return NAME_FULL;
     39 
     40   return storable_type;
     41 }
     42 
     43 // Fills |distinguishing_fields| with a list of fields to use when creating
     44 // labels that can help to distinguish between two profiles. Draws fields from
     45 // |suggested_fields| if it is non-NULL; otherwise returns a default list.
     46 // If |suggested_fields| is non-NULL, does not include |excluded_field| in the
     47 // list. Otherwise, |excluded_field| is ignored, and should be set to
     48 // |UNKNOWN_TYPE| by convention. The resulting list of fields is sorted in
     49 // decreasing order of importance.
     50 void GetFieldsForDistinguishingProfiles(
     51     const std::vector<ServerFieldType>* suggested_fields,
     52     ServerFieldType excluded_field,
     53     std::vector<ServerFieldType>* distinguishing_fields) {
     54   static const ServerFieldType kDefaultDistinguishingFields[] = {
     55     NAME_FULL,
     56     ADDRESS_HOME_LINE1,
     57     ADDRESS_HOME_LINE2,
     58     ADDRESS_HOME_CITY,
     59     ADDRESS_HOME_STATE,
     60     ADDRESS_HOME_ZIP,
     61     ADDRESS_HOME_COUNTRY,
     62     EMAIL_ADDRESS,
     63     PHONE_HOME_WHOLE_NUMBER,
     64     COMPANY_NAME,
     65   };
     66 
     67   if (!suggested_fields) {
     68     DCHECK_EQ(excluded_field, UNKNOWN_TYPE);
     69     distinguishing_fields->assign(
     70         kDefaultDistinguishingFields,
     71         kDefaultDistinguishingFields + arraysize(kDefaultDistinguishingFields));
     72     return;
     73   }
     74 
     75   // Keep track of which fields we've seen so that we avoid duplicate entries.
     76   // Always ignore fields of unknown type and the excluded field.
     77   std::set<ServerFieldType> seen_fields;
     78   seen_fields.insert(UNKNOWN_TYPE);
     79   seen_fields.insert(GetStorableTypeCollapsingNames(excluded_field));
     80 
     81   distinguishing_fields->clear();
     82   for (std::vector<ServerFieldType>::const_iterator it =
     83            suggested_fields->begin();
     84        it != suggested_fields->end(); ++it) {
     85     ServerFieldType suggested_type = GetStorableTypeCollapsingNames(*it);
     86     if (seen_fields.insert(suggested_type).second)
     87       distinguishing_fields->push_back(suggested_type);
     88   }
     89 
     90   // Special case: If the excluded field is a partial name (e.g. first name) and
     91   // the suggested fields include other name fields, include |NAME_FULL| in the
     92   // list of distinguishing fields as a last-ditch fallback. This allows us to
     93   // distinguish between profiles that are identical except for the name.
     94   if (excluded_field != NAME_FULL &&
     95       GetStorableTypeCollapsingNames(excluded_field) == NAME_FULL) {
     96     for (std::vector<ServerFieldType>::const_iterator it =
     97              suggested_fields->begin();
     98          it != suggested_fields->end(); ++it) {
     99       if (*it != excluded_field &&
    100           GetStorableTypeCollapsingNames(*it) == NAME_FULL) {
    101         distinguishing_fields->push_back(NAME_FULL);
    102         break;
    103       }
    104     }
    105   }
    106 }
    107 
    108 // A helper function for string streaming.  Concatenates multi-valued entries
    109 // stored for a given |type| into a single string.  This string is returned.
    110 const base::string16 MultiString(const AutofillProfile& p,
    111                                  ServerFieldType type) {
    112   std::vector<base::string16> values;
    113   p.GetRawMultiInfo(type, &values);
    114   base::string16 accumulate;
    115   for (size_t i = 0; i < values.size(); ++i) {
    116     if (i > 0)
    117       accumulate += ASCIIToUTF16(" ");
    118     accumulate += values[i];
    119   }
    120   return accumulate;
    121 }
    122 
    123 base::string16 GetFormGroupInfo(const FormGroup& form_group,
    124                                 const AutofillType& type,
    125                                 const std::string& app_locale) {
    126   return app_locale.empty() ?
    127       form_group.GetRawInfo(type.GetStorableType()) :
    128       form_group.GetInfo(type, app_locale);
    129 }
    130 
    131 template <class T>
    132 void CopyValuesToItems(ServerFieldType type,
    133                        const std::vector<base::string16>& values,
    134                        std::vector<T>* form_group_items,
    135                        const T& prototype) {
    136   form_group_items->resize(values.size(), prototype);
    137   for (size_t i = 0; i < form_group_items->size(); ++i) {
    138     (*form_group_items)[i].SetRawInfo(type,
    139                                       CollapseWhitespace(values[i], false));
    140   }
    141   // Must have at least one (possibly empty) element.
    142   if (form_group_items->empty())
    143     form_group_items->resize(1, prototype);
    144 }
    145 
    146 template <class T>
    147 void CopyItemsToValues(const AutofillType& type,
    148                        const std::vector<T>& form_group_items,
    149                        const std::string& app_locale,
    150                        std::vector<base::string16>* values) {
    151   values->resize(form_group_items.size());
    152   for (size_t i = 0; i < values->size(); ++i) {
    153     (*values)[i] = GetFormGroupInfo(form_group_items[i], type, app_locale);
    154   }
    155 }
    156 
    157 // Collapse compound field types to their "full" type.  I.e. First name
    158 // collapses to full name, area code collapses to full phone, etc.
    159 void CollapseCompoundFieldTypes(ServerFieldTypeSet* type_set) {
    160   ServerFieldTypeSet collapsed_set;
    161   for (ServerFieldTypeSet::iterator it = type_set->begin();
    162        it != type_set->end(); ++it) {
    163     switch (*it) {
    164       case NAME_FIRST:
    165       case NAME_MIDDLE:
    166       case NAME_LAST:
    167       case NAME_MIDDLE_INITIAL:
    168       case NAME_FULL:
    169       case NAME_SUFFIX:
    170         collapsed_set.insert(NAME_FULL);
    171         break;
    172 
    173       case PHONE_HOME_NUMBER:
    174       case PHONE_HOME_CITY_CODE:
    175       case PHONE_HOME_COUNTRY_CODE:
    176       case PHONE_HOME_CITY_AND_NUMBER:
    177       case PHONE_HOME_WHOLE_NUMBER:
    178         collapsed_set.insert(PHONE_HOME_WHOLE_NUMBER);
    179         break;
    180 
    181       default:
    182         collapsed_set.insert(*it);
    183     }
    184   }
    185   std::swap(*type_set, collapsed_set);
    186 }
    187 
    188 class FindByPhone {
    189  public:
    190   FindByPhone(const base::string16& phone,
    191               const std::string& country_code,
    192               const std::string& app_locale)
    193       : phone_(phone),
    194         country_code_(country_code),
    195         app_locale_(app_locale) {
    196   }
    197 
    198   bool operator()(const base::string16& phone) {
    199     return i18n::PhoneNumbersMatch(phone, phone_, country_code_, app_locale_);
    200   }
    201 
    202   bool operator()(const base::string16* phone) {
    203     return i18n::PhoneNumbersMatch(*phone, phone_, country_code_, app_locale_);
    204   }
    205 
    206  private:
    207   base::string16 phone_;
    208   std::string country_code_;
    209   std::string app_locale_;
    210 };
    211 
    212 // Functor used to check for case-insensitive equality of two strings.
    213 struct CaseInsensitiveStringEquals
    214     : public std::binary_function<base::string16, base::string16, bool>
    215 {
    216   bool operator()(const base::string16& x, const base::string16& y) const {
    217     return
    218         x.size() == y.size() && StringToLowerASCII(x) == StringToLowerASCII(y);
    219   }
    220 };
    221 
    222 }  // namespace
    223 
    224 AutofillProfile::AutofillProfile(const std::string& guid,
    225                                  const std::string& origin)
    226     : AutofillDataModel(guid, origin),
    227       name_(1),
    228       email_(1),
    229       phone_number_(1, PhoneNumber(this)) {
    230 }
    231 
    232 AutofillProfile::AutofillProfile()
    233     : AutofillDataModel(base::GenerateGUID(), std::string()),
    234       name_(1),
    235       email_(1),
    236       phone_number_(1, PhoneNumber(this)) {
    237 }
    238 
    239 AutofillProfile::AutofillProfile(const AutofillProfile& profile)
    240     : AutofillDataModel(std::string(), std::string()) {
    241   operator=(profile);
    242 }
    243 
    244 AutofillProfile::~AutofillProfile() {
    245 }
    246 
    247 AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {
    248   if (this == &profile)
    249     return *this;
    250 
    251   set_guid(profile.guid());
    252   set_origin(profile.origin());
    253 
    254   label_ = profile.label_;
    255   name_ = profile.name_;
    256   email_ = profile.email_;
    257   company_ = profile.company_;
    258   phone_number_ = profile.phone_number_;
    259 
    260   for (size_t i = 0; i < phone_number_.size(); ++i)
    261     phone_number_[i].set_profile(this);
    262 
    263   address_ = profile.address_;
    264 
    265   return *this;
    266 }
    267 
    268 void AutofillProfile::GetMatchingTypes(
    269     const base::string16& text,
    270     const std::string& app_locale,
    271     ServerFieldTypeSet* matching_types) const {
    272   FormGroupList info = FormGroups();
    273   for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
    274     (*it)->GetMatchingTypes(text, app_locale, matching_types);
    275 }
    276 
    277 base::string16 AutofillProfile::GetRawInfo(ServerFieldType type) const {
    278   const FormGroup* form_group = FormGroupForType(AutofillType(type));
    279   if (!form_group)
    280     return base::string16();
    281 
    282   return form_group->GetRawInfo(type);
    283 }
    284 
    285 void AutofillProfile::SetRawInfo(ServerFieldType type,
    286                                  const base::string16& value) {
    287   FormGroup* form_group = MutableFormGroupForType(AutofillType(type));
    288   if (form_group)
    289     form_group->SetRawInfo(type, CollapseWhitespace(value, false));
    290 }
    291 
    292 base::string16 AutofillProfile::GetInfo(const AutofillType& type,
    293                                         const std::string& app_locale) const {
    294   const FormGroup* form_group = FormGroupForType(type);
    295   if (!form_group)
    296     return base::string16();
    297 
    298   return form_group->GetInfo(type, app_locale);
    299 }
    300 
    301 bool AutofillProfile::SetInfo(const AutofillType& type,
    302                               const base::string16& value,
    303                               const std::string& app_locale) {
    304   FormGroup* form_group = MutableFormGroupForType(type);
    305   if (!form_group)
    306     return false;
    307 
    308   return
    309       form_group->SetInfo(type, CollapseWhitespace(value, false), app_locale);
    310 }
    311 
    312 void AutofillProfile::SetRawMultiInfo(
    313     ServerFieldType type,
    314     const std::vector<base::string16>& values) {
    315   switch (AutofillType(type).group()) {
    316     case NAME:
    317     case NAME_BILLING:
    318       CopyValuesToItems(type, values, &name_, NameInfo());
    319       break;
    320     case EMAIL:
    321       CopyValuesToItems(type, values, &email_, EmailInfo());
    322       break;
    323     case PHONE_HOME:
    324     case PHONE_BILLING:
    325       CopyValuesToItems(type,
    326                         values,
    327                         &phone_number_,
    328                         PhoneNumber(this));
    329       break;
    330     default:
    331       if (values.size() == 1) {
    332         SetRawInfo(type, values[0]);
    333       } else if (values.size() == 0) {
    334         SetRawInfo(type, base::string16());
    335       } else {
    336         // Shouldn't attempt to set multiple values on single-valued field.
    337         NOTREACHED();
    338       }
    339       break;
    340   }
    341 }
    342 
    343 void AutofillProfile::GetRawMultiInfo(
    344     ServerFieldType type,
    345     std::vector<base::string16>* values) const {
    346   GetMultiInfoImpl(AutofillType(type), std::string(), values);
    347 }
    348 
    349 void AutofillProfile::GetMultiInfo(const AutofillType& type,
    350                                    const std::string& app_locale,
    351                                    std::vector<base::string16>* values) const {
    352   GetMultiInfoImpl(type, app_locale, values);
    353 }
    354 
    355 void AutofillProfile::FillFormField(const AutofillField& field,
    356                                     size_t variant,
    357                                     const std::string& app_locale,
    358                                     FormFieldData* field_data) const {
    359   AutofillType type = field.Type();
    360   DCHECK_NE(CREDIT_CARD, type.group());
    361   DCHECK(field_data);
    362 
    363   if (type.GetStorableType() == PHONE_HOME_NUMBER) {
    364     FillPhoneNumberField(field, variant, app_locale, field_data);
    365   } else if (field_data->form_control_type == "select-one") {
    366     FillSelectControl(type, app_locale, field_data);
    367   } else {
    368     std::vector<base::string16> values;
    369     GetMultiInfo(type, app_locale, &values);
    370     if (variant >= values.size()) {
    371       // If the variant is unavailable, bail.  This case is reachable, for
    372       // example if Sync updates a profile during the filling process.
    373       return;
    374     }
    375 
    376     field_data->value = values[variant];
    377   }
    378 }
    379 
    380 void AutofillProfile::FillPhoneNumberField(const AutofillField& field,
    381                                            size_t variant,
    382                                            const std::string& app_locale,
    383                                            FormFieldData* field_data) const {
    384   std::vector<base::string16> values;
    385   GetMultiInfo(field.Type(), app_locale, &values);
    386   DCHECK(variant < values.size());
    387 
    388   // If we are filling a phone number, check to see if the size field
    389   // matches the "prefix" or "suffix" sizes and fill accordingly.
    390   base::string16 number = values[variant];
    391   if (number.length() ==
    392           PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
    393     if (field.phone_part() == AutofillField::PHONE_PREFIX ||
    394         field_data->max_length == PhoneNumber::kPrefixLength) {
    395       number = number.substr(PhoneNumber::kPrefixOffset,
    396                              PhoneNumber::kPrefixLength);
    397     } else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
    398                field_data->max_length == PhoneNumber::kSuffixLength) {
    399       number = number.substr(PhoneNumber::kSuffixOffset,
    400                              PhoneNumber::kSuffixLength);
    401     }
    402   }
    403 
    404   field_data->value = number;
    405 }
    406 
    407 const base::string16 AutofillProfile::Label() const {
    408   return label_;
    409 }
    410 
    411 bool AutofillProfile::IsEmpty(const std::string& app_locale) const {
    412   ServerFieldTypeSet types;
    413   GetNonEmptyTypes(app_locale, &types);
    414   return types.empty();
    415 }
    416 
    417 bool AutofillProfile::IsPresentButInvalid(ServerFieldType type) const {
    418   std::string country = UTF16ToUTF8(GetRawInfo(ADDRESS_HOME_COUNTRY));
    419   base::string16 data = GetRawInfo(type);
    420   switch (type) {
    421     case ADDRESS_HOME_STATE:
    422       if (!data.empty() && country == "US" && !autofill::IsValidState(data))
    423         return true;
    424       break;
    425 
    426     case ADDRESS_HOME_ZIP:
    427       if (!data.empty() && country == "US" && !autofill::IsValidZip(data))
    428         return true;
    429       break;
    430 
    431     case PHONE_HOME_WHOLE_NUMBER: {
    432       if (!data.empty() && !i18n::PhoneObject(data, country).IsValidNumber())
    433         return true;
    434       break;
    435     }
    436 
    437     default:
    438       NOTREACHED();
    439       break;
    440   }
    441 
    442   return false;
    443 }
    444 
    445 
    446 int AutofillProfile::Compare(const AutofillProfile& profile) const {
    447   const ServerFieldType single_value_types[] = { COMPANY_NAME,
    448                                                  ADDRESS_HOME_LINE1,
    449                                                  ADDRESS_HOME_LINE2,
    450                                                  ADDRESS_HOME_CITY,
    451                                                  ADDRESS_HOME_STATE,
    452                                                  ADDRESS_HOME_ZIP,
    453                                                  ADDRESS_HOME_COUNTRY };
    454 
    455   for (size_t i = 0; i < arraysize(single_value_types); ++i) {
    456     int comparison = GetRawInfo(single_value_types[i]).compare(
    457         profile.GetRawInfo(single_value_types[i]));
    458     if (comparison != 0)
    459       return comparison;
    460   }
    461 
    462   const ServerFieldType multi_value_types[] = { NAME_FIRST,
    463                                                 NAME_MIDDLE,
    464                                                 NAME_LAST,
    465                                                 EMAIL_ADDRESS,
    466                                                 PHONE_HOME_WHOLE_NUMBER };
    467 
    468   for (size_t i = 0; i < arraysize(multi_value_types); ++i) {
    469     std::vector<base::string16> values_a;
    470     std::vector<base::string16> values_b;
    471     GetRawMultiInfo(multi_value_types[i], &values_a);
    472     profile.GetRawMultiInfo(multi_value_types[i], &values_b);
    473     if (values_a.size() < values_b.size())
    474       return -1;
    475     if (values_a.size() > values_b.size())
    476       return 1;
    477     for (size_t j = 0; j < values_a.size(); ++j) {
    478       int comparison = values_a[j].compare(values_b[j]);
    479       if (comparison != 0)
    480         return comparison;
    481     }
    482   }
    483 
    484   return 0;
    485 }
    486 
    487 bool AutofillProfile::operator==(const AutofillProfile& profile) const {
    488   return guid() == profile.guid() &&
    489          origin() == profile.origin() &&
    490          Compare(profile) == 0;
    491 }
    492 
    493 bool AutofillProfile::operator!=(const AutofillProfile& profile) const {
    494   return !operator==(profile);
    495 }
    496 
    497 const base::string16 AutofillProfile::PrimaryValue() const {
    498   return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY);
    499 }
    500 
    501 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile,
    502                                  const std::string& app_locale) const {
    503   ServerFieldTypeSet types;
    504   GetNonEmptyTypes(app_locale, &types);
    505 
    506   for (ServerFieldTypeSet::const_iterator it = types.begin(); it != types.end();
    507        ++it) {
    508     if (*it == NAME_FULL) {
    509       // Ignore the compound "full name" field type.  We are only interested in
    510       // comparing the constituent parts.  For example, if |this| has a middle
    511       // name saved, but |profile| lacks one, |profile| could still be a subset
    512       // of |this|.
    513       continue;
    514     } else if (AutofillType(*it).group() == PHONE_HOME) {
    515       // Phone numbers should be canonicalized prior to being compared.
    516       if (*it != PHONE_HOME_WHOLE_NUMBER) {
    517         continue;
    518       } else if (!i18n::PhoneNumbersMatch(
    519             GetRawInfo(*it),
    520             profile.GetRawInfo(*it),
    521             UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)),
    522             app_locale)) {
    523         return false;
    524       }
    525     } else if (StringToLowerASCII(GetRawInfo(*it)) !=
    526                    StringToLowerASCII(profile.GetRawInfo(*it))) {
    527       return false;
    528     }
    529   }
    530 
    531   return true;
    532 }
    533 
    534 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile,
    535                                            const std::string& app_locale) {
    536   // Verified profiles should never be overwritten with unverified data.
    537   DCHECK(!IsVerified() || profile.IsVerified());
    538   set_origin(profile.origin());
    539 
    540   ServerFieldTypeSet field_types;
    541   profile.GetNonEmptyTypes(app_locale, &field_types);
    542 
    543   // Only transfer "full" types (e.g. full name) and not fragments (e.g.
    544   // first name, last name).
    545   CollapseCompoundFieldTypes(&field_types);
    546 
    547   for (ServerFieldTypeSet::const_iterator iter = field_types.begin();
    548        iter != field_types.end(); ++iter) {
    549     if (AutofillProfile::SupportsMultiValue(*iter)) {
    550       std::vector<base::string16> new_values;
    551       profile.GetRawMultiInfo(*iter, &new_values);
    552       std::vector<base::string16> existing_values;
    553       GetRawMultiInfo(*iter, &existing_values);
    554 
    555       // GetMultiInfo always returns at least one element, even if the profile
    556       // has no data stored for this field type.
    557       if (existing_values.size() == 1 && existing_values.front().empty())
    558         existing_values.clear();
    559 
    560       FieldTypeGroup group = AutofillType(*iter).group();
    561       for (std::vector<base::string16>::iterator value_iter =
    562                new_values.begin();
    563            value_iter != new_values.end(); ++value_iter) {
    564         // Don't add duplicates.
    565         if (group == PHONE_HOME) {
    566           AddPhoneIfUnique(*value_iter, app_locale, &existing_values);
    567         } else {
    568           std::vector<base::string16>::const_iterator existing_iter =
    569               std::find_if(
    570                   existing_values.begin(), existing_values.end(),
    571                   std::bind1st(CaseInsensitiveStringEquals(), *value_iter));
    572           if (existing_iter == existing_values.end())
    573             existing_values.insert(existing_values.end(), *value_iter);
    574         }
    575       }
    576       SetRawMultiInfo(*iter, existing_values);
    577     } else {
    578       base::string16 new_value = profile.GetRawInfo(*iter);
    579       if (StringToLowerASCII(GetRawInfo(*iter)) !=
    580               StringToLowerASCII(new_value)) {
    581         SetRawInfo(*iter, new_value);
    582       }
    583     }
    584   }
    585 }
    586 
    587 // static
    588 bool AutofillProfile::SupportsMultiValue(ServerFieldType type) {
    589   FieldTypeGroup group = AutofillType(type).group();
    590   return group == NAME ||
    591          group == NAME_BILLING ||
    592          group == EMAIL ||
    593          group == PHONE_HOME ||
    594          group == PHONE_BILLING;
    595 }
    596 
    597 // static
    598 bool AutofillProfile::AdjustInferredLabels(
    599     std::vector<AutofillProfile*>* profiles) {
    600   const size_t kMinimalFieldsShown = 2;
    601 
    602   std::vector<base::string16> created_labels;
    603   CreateInferredLabels(profiles, NULL, UNKNOWN_TYPE, kMinimalFieldsShown,
    604                        &created_labels);
    605   DCHECK_EQ(profiles->size(), created_labels.size());
    606 
    607   bool updated_labels = false;
    608   for (size_t i = 0; i < profiles->size(); ++i) {
    609     if ((*profiles)[i]->Label() != created_labels[i]) {
    610       updated_labels = true;
    611       (*profiles)[i]->label_ = created_labels[i];
    612     }
    613   }
    614   return updated_labels;
    615 }
    616 
    617 // static
    618 void AutofillProfile::CreateInferredLabels(
    619     const std::vector<AutofillProfile*>* profiles,
    620     const std::vector<ServerFieldType>* suggested_fields,
    621     ServerFieldType excluded_field,
    622     size_t minimal_fields_shown,
    623     std::vector<base::string16>* created_labels) {
    624   DCHECK(profiles);
    625   DCHECK(created_labels);
    626 
    627   std::vector<ServerFieldType> fields_to_use;
    628   GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field,
    629                                      &fields_to_use);
    630 
    631   // Construct the default label for each profile. Also construct a map that
    632   // associates each label with the profiles that have this label. This map is
    633   // then used to detect which labels need further differentiating fields.
    634   std::map<base::string16, std::list<size_t> > labels;
    635   for (size_t i = 0; i < profiles->size(); ++i) {
    636     base::string16 label =
    637         (*profiles)[i]->ConstructInferredLabel(fields_to_use,
    638                                                minimal_fields_shown);
    639     labels[label].push_back(i);
    640   }
    641 
    642   created_labels->resize(profiles->size());
    643   for (std::map<base::string16, std::list<size_t> >::const_iterator it =
    644            labels.begin();
    645        it != labels.end(); ++it) {
    646     if (it->second.size() == 1) {
    647       // This label is unique, so use it without any further ado.
    648       base::string16 label = it->first;
    649       size_t profile_index = it->second.front();
    650       (*created_labels)[profile_index] = label;
    651     } else {
    652       // We have more than one profile with the same label, so add
    653       // differentiating fields.
    654       CreateDifferentiatingLabels(*profiles, it->second, fields_to_use,
    655                                   minimal_fields_shown, created_labels);
    656     }
    657   }
    658 }
    659 
    660 void AutofillProfile::GetSupportedTypes(
    661     ServerFieldTypeSet* supported_types) const {
    662   FormGroupList info = FormGroups();
    663   for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
    664     (*it)->GetSupportedTypes(supported_types);
    665 }
    666 
    667 bool AutofillProfile::FillCountrySelectControl(
    668     const std::string& app_locale,
    669     FormFieldData* field_data) const {
    670   std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
    671 
    672   DCHECK_EQ(field_data->option_values.size(),
    673             field_data->option_contents.size());
    674   for (size_t i = 0; i < field_data->option_values.size(); ++i) {
    675     // Canonicalize each <option> value to a country code, and compare to the
    676     // target country code.
    677     base::string16 value = field_data->option_values[i];
    678     base::string16 contents = field_data->option_contents[i];
    679     if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
    680         country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
    681       field_data->value = value;
    682       return true;
    683     }
    684   }
    685 
    686   return false;
    687 }
    688 
    689 void AutofillProfile::GetMultiInfoImpl(
    690     const AutofillType& type,
    691     const std::string& app_locale,
    692     std::vector<base::string16>* values) const {
    693   switch (type.group()) {
    694     case NAME:
    695     case NAME_BILLING:
    696       CopyItemsToValues(type, name_, app_locale, values);
    697       break;
    698     case EMAIL:
    699       CopyItemsToValues(type, email_, app_locale, values);
    700       break;
    701     case PHONE_HOME:
    702     case PHONE_BILLING:
    703       CopyItemsToValues(type, phone_number_, app_locale, values);
    704       break;
    705     default:
    706       values->resize(1);
    707       (*values)[0] = GetFormGroupInfo(*this, type, app_locale);
    708   }
    709 }
    710 
    711 void AutofillProfile::AddPhoneIfUnique(
    712     const base::string16& phone,
    713     const std::string& app_locale,
    714     std::vector<base::string16>* existing_phones) {
    715   DCHECK(existing_phones);
    716   // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377",
    717   // "(800)356-9377" and "356-9377" are considered the same.
    718   std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
    719   if (std::find_if(existing_phones->begin(), existing_phones->end(),
    720                    FindByPhone(phone, country_code, app_locale)) ==
    721       existing_phones->end()) {
    722     existing_phones->push_back(phone);
    723   }
    724 }
    725 
    726 base::string16 AutofillProfile::ConstructInferredLabel(
    727     const std::vector<ServerFieldType>& included_fields,
    728     size_t num_fields_to_use) const {
    729   const base::string16 separator =
    730       l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
    731 
    732   base::string16 label;
    733   size_t num_fields_used = 0;
    734   for (std::vector<ServerFieldType>::const_iterator it =
    735            included_fields.begin();
    736        it != included_fields.end() && num_fields_used < num_fields_to_use;
    737        ++it) {
    738     base::string16 field = GetRawInfo(*it);
    739     if (field.empty())
    740       continue;
    741 
    742     if (!label.empty())
    743       label.append(separator);
    744 
    745     label.append(field);
    746     ++num_fields_used;
    747   }
    748   return label;
    749 }
    750 
    751 // static
    752 void AutofillProfile::CreateDifferentiatingLabels(
    753     const std::vector<AutofillProfile*>& profiles,
    754     const std::list<size_t>& indices,
    755     const std::vector<ServerFieldType>& fields,
    756     size_t num_fields_to_include,
    757     std::vector<base::string16>* created_labels) {
    758   // For efficiency, we first construct a map of fields to their text values and
    759   // each value's frequency.
    760   std::map<ServerFieldType,
    761            std::map<base::string16, size_t> > field_text_frequencies_by_field;
    762   for (std::vector<ServerFieldType>::const_iterator field = fields.begin();
    763        field != fields.end(); ++field) {
    764     std::map<base::string16, size_t>& field_text_frequencies =
    765         field_text_frequencies_by_field[*field];
    766 
    767     for (std::list<size_t>::const_iterator it = indices.begin();
    768          it != indices.end(); ++it) {
    769       const AutofillProfile* profile = profiles[*it];
    770       base::string16 field_text = profile->GetRawInfo(*field);
    771 
    772       // If this label is not already in the map, add it with frequency 0.
    773       if (!field_text_frequencies.count(field_text))
    774         field_text_frequencies[field_text] = 0;
    775 
    776       // Now, increment the frequency for this label.
    777       ++field_text_frequencies[field_text];
    778     }
    779   }
    780 
    781   // Now comes the meat of the algorithm. For each profile, we scan the list of
    782   // fields to use, looking for two things:
    783   //  1. A (non-empty) field that differentiates the profile from all others
    784   //  2. At least |num_fields_to_include| non-empty fields
    785   // Before we've satisfied condition (2), we include all fields, even ones that
    786   // are identical across all the profiles. Once we've satisfied condition (2),
    787   // we only include fields that that have at last two distinct values.
    788   for (std::list<size_t>::const_iterator it = indices.begin();
    789        it != indices.end(); ++it) {
    790     const AutofillProfile* profile = profiles[*it];
    791 
    792     std::vector<ServerFieldType> label_fields;
    793     bool found_differentiating_field = false;
    794     for (std::vector<ServerFieldType>::const_iterator field = fields.begin();
    795          field != fields.end(); ++field) {
    796       // Skip over empty fields.
    797       base::string16 field_text = profile->GetRawInfo(*field);
    798       if (field_text.empty())
    799         continue;
    800 
    801       std::map<base::string16, size_t>& field_text_frequencies =
    802           field_text_frequencies_by_field[*field];
    803       found_differentiating_field |=
    804           !field_text_frequencies.count(base::string16()) &&
    805           (field_text_frequencies[field_text] == 1);
    806 
    807       // Once we've found enough non-empty fields, skip over any remaining
    808       // fields that are identical across all the profiles.
    809       if (label_fields.size() >= num_fields_to_include &&
    810           (field_text_frequencies.size() == 1))
    811         continue;
    812 
    813       label_fields.push_back(*field);
    814 
    815       // If we've (1) found a differentiating field and (2) found at least
    816       // |num_fields_to_include| non-empty fields, we're done!
    817       if (found_differentiating_field &&
    818           label_fields.size() >= num_fields_to_include)
    819         break;
    820     }
    821 
    822     (*created_labels)[*it] =
    823         profile->ConstructInferredLabel(label_fields,
    824                                         label_fields.size());
    825   }
    826 }
    827 
    828 AutofillProfile::FormGroupList AutofillProfile::FormGroups() const {
    829   FormGroupList v(5);
    830   v[0] = &name_[0];
    831   v[1] = &email_[0];
    832   v[2] = &company_;
    833   v[3] = &phone_number_[0];
    834   v[4] = &address_;
    835   return v;
    836 }
    837 
    838 const FormGroup* AutofillProfile::FormGroupForType(
    839     const AutofillType& type) const {
    840   return const_cast<AutofillProfile*>(this)->MutableFormGroupForType(type);
    841 }
    842 
    843 FormGroup* AutofillProfile::MutableFormGroupForType(const AutofillType& type) {
    844   switch (type.group()) {
    845     case NAME:
    846     case NAME_BILLING:
    847       return &name_[0];
    848 
    849     case EMAIL:
    850       return &email_[0];
    851 
    852     case COMPANY:
    853       return &company_;
    854 
    855     case PHONE_HOME:
    856     case PHONE_BILLING:
    857       return &phone_number_[0];
    858 
    859     case ADDRESS_HOME:
    860     case ADDRESS_BILLING:
    861       return &address_;
    862 
    863     case NO_GROUP:
    864     case CREDIT_CARD:
    865         return NULL;
    866   }
    867 
    868   NOTREACHED();
    869   return NULL;
    870 }
    871 
    872 // So we can compare AutofillProfiles with EXPECT_EQ().
    873 std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
    874   return os
    875       << UTF16ToUTF8(profile.Label())
    876       << " "
    877       << profile.guid()
    878       << " "
    879       << profile.origin()
    880       << " "
    881       << UTF16ToUTF8(MultiString(profile, NAME_FIRST))
    882       << " "
    883       << UTF16ToUTF8(MultiString(profile, NAME_MIDDLE))
    884       << " "
    885       << UTF16ToUTF8(MultiString(profile, NAME_LAST))
    886       << " "
    887       << UTF16ToUTF8(MultiString(profile, EMAIL_ADDRESS))
    888       << " "
    889       << UTF16ToUTF8(profile.GetRawInfo(COMPANY_NAME))
    890       << " "
    891       << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE1))
    892       << " "
    893       << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE2))
    894       << " "
    895       << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY))
    896       << " "
    897       << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE))
    898       << " "
    899       << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP))
    900       << " "
    901       << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))
    902       << " "
    903       << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER));
    904 }
    905 
    906 }  // namespace autofill
    907