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