1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// Copyright 2013 The Chromium Authors. All rights reserved.
2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// Use of this source code is governed by a BSD-style license that can be
3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// found in the LICENSE file.
4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com
5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#include "components/autofill/core/browser/autofill_profile.h"
6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com
7cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#include <algorithm>
8cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#include <functional>
9cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#include <map>
108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include <ostream>
118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include <set>
128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "base/basictypes.h"
148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "base/guid.h"
158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "base/logging.h"
168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "base/strings/string_util.h"
178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "base/strings/utf_string_conversions.h"
188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/address.h"
198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/address_i18n.h"
208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/autofill_country.h"
218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/autofill_field.h"
228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/autofill_type.h"
238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/contact_info.h"
248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/phone_number.h"
258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/phone_number_i18n.h"
268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/browser/validation.h"
278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "components/autofill/core/common/form_field_data.h"
288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "grit/components_strings.h"
298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "third_party/libaddressinput/chromium/addressinput_util.h"
308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h"
338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "ui/base/l10n/l10n_util.h"
348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comusing base::ASCIIToUTF16;
368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comusing base::UTF16ToUTF8;
378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comusing i18n::addressinput::AddressData;
388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comusing i18n::addressinput::AddressField;
398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comnamespace autofill {
418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comnamespace {
428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// Like |AutofillType::GetStorableType()|, but also returns |NAME_FULL| for
448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// first, middle, and last name field types.
458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comServerFieldType GetStorableTypeCollapsingNames(ServerFieldType type) {
468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  ServerFieldType storable_type = AutofillType(type).GetStorableType();
478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (AutofillType(storable_type).group() == NAME)
488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return NAME_FULL;
498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return storable_type;
518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// Fills |distinguishing_fields| with a list of fields to use when creating
548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// labels that can help to distinguish between two profiles. Draws fields from
558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// |suggested_fields| if it is non-NULL; otherwise returns a default list.
568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// If |suggested_fields| is non-NULL, does not include |excluded_field| in the
578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// list. Otherwise, |excluded_field| is ignored, and should be set to
588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// |UNKNOWN_TYPE| by convention. The resulting list of fields is sorted in
598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// decreasing order of importance.
608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid GetFieldsForDistinguishingProfiles(
618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    const std::vector<ServerFieldType>* suggested_fields,
628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ServerFieldType excluded_field,
638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    std::vector<ServerFieldType>* distinguishing_fields) {
648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  static const ServerFieldType kDefaultDistinguishingFields[] = {
658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    NAME_FULL,
668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_LINE1,
678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_LINE2,
688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_DEPENDENT_LOCALITY,
698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_CITY,
708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_STATE,
718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_ZIP,
728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_SORTING_CODE,
738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_COUNTRY,
748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    EMAIL_ADDRESS,
758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    PHONE_HOME_WHOLE_NUMBER,
768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    COMPANY_NAME,
778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  };
788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::vector<ServerFieldType> default_fields;
808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (!suggested_fields) {
818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    default_fields.assign(
828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        kDefaultDistinguishingFields,
838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        kDefaultDistinguishingFields + arraysize(kDefaultDistinguishingFields));
848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (excluded_field == UNKNOWN_TYPE) {
858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      distinguishing_fields->swap(default_fields);
868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return;
878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    }
888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    suggested_fields = &default_fields;
898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // Keep track of which fields we've seen so that we avoid duplicate entries.
928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // Always ignore fields of unknown type and the excluded field.
938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::set<ServerFieldType> seen_fields;
948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  seen_fields.insert(UNKNOWN_TYPE);
958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  seen_fields.insert(GetStorableTypeCollapsingNames(excluded_field));
968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  distinguishing_fields->clear();
988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (std::vector<ServerFieldType>::const_iterator it =
998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com           suggested_fields->begin();
1008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com       it != suggested_fields->end(); ++it) {
1018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ServerFieldType suggested_type = GetStorableTypeCollapsingNames(*it);
1028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (seen_fields.insert(suggested_type).second)
1038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      distinguishing_fields->push_back(suggested_type);
1048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
1058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // Special case: If the excluded field is a partial name (e.g. first name) and
1078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // the suggested fields include other name fields, include |NAME_FULL| in the
1088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // list of distinguishing fields as a last-ditch fallback. This allows us to
1098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // distinguish between profiles that are identical except for the name.
1108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (excluded_field != NAME_FULL &&
1118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      GetStorableTypeCollapsingNames(excluded_field) == NAME_FULL) {
1128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    for (std::vector<ServerFieldType>::const_iterator it =
1138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com             suggested_fields->begin();
1148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com         it != suggested_fields->end(); ++it) {
1158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      if (*it != excluded_field &&
1168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com          GetStorableTypeCollapsingNames(*it) == NAME_FULL) {
1178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        distinguishing_fields->push_back(NAME_FULL);
1188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        break;
1198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      }
1208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    }
1218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
1228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
1238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// A helper function for string streaming.  Concatenates multi-valued entries
1258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// stored for a given |type| into a single string.  This string is returned.
1268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comconst base::string16 MultiString(const AutofillProfile& p,
1278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                 ServerFieldType type) {
1288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::vector<base::string16> values;
1298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  p.GetRawMultiInfo(type, &values);
1308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  base::string16 accumulate;
1318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < values.size(); ++i) {
1328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (i > 0)
1338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      accumulate += ASCIIToUTF16(" ");
1348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    accumulate += values[i];
1358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
1368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return accumulate;
1378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
1388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combase::string16 GetFormGroupInfo(const FormGroup& form_group,
1408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                const AutofillType& type,
1418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                const std::string& app_locale) {
1428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return app_locale.empty() ?
1438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      form_group.GetRawInfo(type.GetStorableType()) :
1448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      form_group.GetInfo(type, app_locale);
1458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
1468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comtemplate <class T>
1488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid CopyRawValuesToItems(ServerFieldType type,
1498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                          const std::vector<base::string16>& values,
1508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                          const T& prototype,
1518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                          std::vector<T>* form_group_items) {
1528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  form_group_items->resize(values.size(), prototype);
1538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < form_group_items->size(); ++i) {
1548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    (*form_group_items)[i].SetRawInfo(type, values[i]);
1558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
1568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // Must have at least one (possibly empty) element.
1578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  form_group_items->resize(std::max<size_t>(1UL, values.size()), prototype);
1588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
1598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comtemplate <class T>
1618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid CopyValuesToItems(AutofillType type,
1628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       const std::vector<base::string16>& values,
1638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       const T& prototype,
1648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       const std::string& app_locale,
1658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       std::vector<T>* form_group_items) {
1668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  form_group_items->resize(values.size(), prototype);
1678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < form_group_items->size(); ++i) {
1688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    (*form_group_items)[i].SetInfo(type, values[i], app_locale);
1698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
1708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  // Must have at least one (possibly empty) element.
1718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  form_group_items->resize(std::max<size_t>(1UL, values.size()), prototype);
1728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
1738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comtemplate <class T>
1758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid CopyItemsToValues(const AutofillType& type,
1768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       const std::vector<T>& form_group_items,
1778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       const std::string& app_locale,
1788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                       std::vector<base::string16>* values) {
1798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  values->resize(form_group_items.size());
1808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < values->size(); ++i) {
1818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    (*values)[i] = GetFormGroupInfo(form_group_items[i], type, app_locale);
1828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
1838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
1848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
1858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// Collapse compound field types to their "full" type.  I.e. First name
1868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// collapses to full name, area code collapses to full phone, etc.
1878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid CollapseCompoundFieldTypes(ServerFieldTypeSet* type_set) {
1888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  ServerFieldTypeSet collapsed_set;
1898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (ServerFieldTypeSet::iterator it = type_set->begin();
1908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com       it != type_set->end(); ++it) {
1918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    switch (*it) {
1928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case NAME_FIRST:
1938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case NAME_MIDDLE:
1948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case NAME_LAST:
1958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case NAME_MIDDLE_INITIAL:
1968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case NAME_FULL:
1978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case NAME_SUFFIX:
1988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        collapsed_set.insert(NAME_FULL);
1998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        break;
2008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case PHONE_HOME_NUMBER:
2028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case PHONE_HOME_CITY_CODE:
2038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case PHONE_HOME_COUNTRY_CODE:
2048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case PHONE_HOME_CITY_AND_NUMBER:
2058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      case PHONE_HOME_WHOLE_NUMBER:
2068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        collapsed_set.insert(PHONE_HOME_WHOLE_NUMBER);
2078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        break;
2088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      default:
2108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        collapsed_set.insert(*it);
2118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    }
2128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
2138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::swap(*type_set, collapsed_set);
2148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
2158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comclass FindByPhone {
2178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public:
2188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  FindByPhone(const base::string16& phone,
2198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com              const std::string& country_code,
2208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com              const std::string& app_locale)
2218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      : phone_(phone),
2228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        country_code_(country_code),
2238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        app_locale_(app_locale) {}
2248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  bool operator()(const base::string16& phone) {
2268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return i18n::PhoneNumbersMatch(phone, phone_, country_code_, app_locale_);
2278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
2288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private:
2308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  base::string16 phone_;
2318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::string country_code_;
2328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::string app_locale_;
2338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com};
2348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// Functor used to check for case-insensitive equality of two strings.
2368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comstruct CaseInsensitiveStringEquals {
2378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public:
2388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  CaseInsensitiveStringEquals(const base::string16& other)
2398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      : other_(other) {}
2408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  bool operator()(const base::string16& x) const {
2428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return x.size() == other_.size() &&
2438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        base::StringToLowerASCII(x) == base::StringToLowerASCII(other_);
2448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
2458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private:
2478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  const base::string16& other_;
2488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com};
2498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}  // namespace
2518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comAutofillProfile::AutofillProfile(const std::string& guid,
2538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                 const std::string& origin)
2548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    : AutofillDataModel(guid, origin),
2558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      name_(1),
2568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      email_(1),
2578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      phone_number_(1, PhoneNumber(this)) {
2588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
2598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comAutofillProfile::AutofillProfile()
2618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    : AutofillDataModel(base::GenerateGUID(), std::string()),
2628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      name_(1),
2638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      email_(1),
2648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      phone_number_(1, PhoneNumber(this)) {
2658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
2668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comAutofillProfile::AutofillProfile(const AutofillProfile& profile)
2688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    : AutofillDataModel(std::string(), std::string()) {
2698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  operator=(profile);
2708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
2718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comAutofillProfile::~AutofillProfile() {
2738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
2748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comAutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {
2768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (this == &profile)
2778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return *this;
2788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  set_guid(profile.guid());
2808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  set_origin(profile.origin());
2818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  name_ = profile.name_;
2838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  email_ = profile.email_;
2848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  company_ = profile.company_;
2858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  phone_number_ = profile.phone_number_;
2868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < phone_number_.size(); ++i)
2888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    phone_number_[i].set_profile(this);
2898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  address_ = profile.address_;
2918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  set_language_code(profile.language_code());
2928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return *this;
2948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
2958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
2968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid AutofillProfile::GetMatchingTypes(
2978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    const base::string16& text,
2988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    const std::string& app_locale,
2998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ServerFieldTypeSet* matching_types) const {
3008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  FormGroupList info = FormGroups();
3018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
3028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    (*it)->GetMatchingTypes(text, app_locale, matching_types);
3038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combase::string16 AutofillProfile::GetRawInfo(ServerFieldType type) const {
3068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  const FormGroup* form_group = FormGroupForType(AutofillType(type));
3078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (!form_group)
3088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return base::string16();
3098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return form_group->GetRawInfo(type);
3118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid AutofillProfile::SetRawInfo(ServerFieldType type,
3148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                 const base::string16& value) {
3158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  FormGroup* form_group = MutableFormGroupForType(AutofillType(type));
3168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (form_group)
3178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    form_group->SetRawInfo(type, value);
3188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combase::string16 AutofillProfile::GetInfo(const AutofillType& type,
3218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                        const std::string& app_locale) const {
3228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (type.html_type() == HTML_TYPE_FULL_ADDRESS) {
3238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    scoped_ptr<AddressData> address_data =
3248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        i18n::CreateAddressDataFromAutofillProfile(*this, app_locale);
3258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (!addressinput::HasAllRequiredFields(*address_data))
3268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return base::string16();
3278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    std::vector<std::string> lines;
3298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ::i18n::addressinput::GetFormattedNationalAddress(*address_data, &lines);
3308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return base::UTF8ToUTF16(JoinString(lines, '\n'));
3318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
3328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  const FormGroup* form_group = FormGroupForType(type);
3348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (!form_group)
3358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return base::string16();
3368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return form_group->GetInfo(type, app_locale);
3388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::SetInfo(const AutofillType& type,
3418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                              const base::string16& value,
3428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                              const std::string& app_locale) {
3438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  FormGroup* form_group = MutableFormGroupForType(type);
3448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (!form_group)
3458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return false;
3468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  base::string16 trimmed_value;
3488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  base::TrimWhitespace(value, base::TRIM_ALL, &trimmed_value);
3498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return form_group->SetInfo(type, trimmed_value, app_locale);
3508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combase::string16 AutofillProfile::GetInfoForVariant(
3538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    const AutofillType& type,
3548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    size_t variant,
3558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    const std::string& app_locale) const {
3568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::vector<base::string16> values;
3578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  GetMultiInfo(type, app_locale, &values);
3588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (variant >= values.size()) {
3608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    // If the variant is unavailable, bail. This case is reachable, for
3618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    // example if Sync updates a profile during the filling process.
3628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return base::string16();
3638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
3648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return values[variant];
3668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid AutofillProfile::SetRawMultiInfo(
3698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ServerFieldType type,
3708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    const std::vector<base::string16>& values) {
3718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  switch (AutofillType(type).group()) {
3728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case NAME:
3738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case NAME_BILLING:
3748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      CopyRawValuesToItems(type, values, NameInfo(), &name_);
3758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
3768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case EMAIL:
3788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      CopyRawValuesToItems(type, values, EmailInfo(), &email_);
3798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
3808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case PHONE_HOME:
3828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case PHONE_BILLING:
3838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      CopyRawValuesToItems(type, values, PhoneNumber(this), &phone_number_);
3848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
3858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    default:
3878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      if (values.size() == 1U) {
3888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        SetRawInfo(type, values[0]);
3898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      } else if (values.empty()) {
3908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        SetRawInfo(type, base::string16());
3918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      } else {
3928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        // Shouldn't attempt to set multiple values on single-valued field.
3938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        NOTREACHED();
3948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      }
3958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
3968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
3978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
3988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
3998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid AutofillProfile::GetRawMultiInfo(
4008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ServerFieldType type,
4018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    std::vector<base::string16>* values) const {
4028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  GetMultiInfoImpl(AutofillType(type), std::string(), values);
4038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
4048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid AutofillProfile::SetMultiInfo(const AutofillType& type,
4068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                   const std::vector<base::string16>& values,
4078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                   const std::string& app_locale) {
4088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  switch (AutofillType(type).group()) {
4098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case NAME:
4108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case NAME_BILLING:
4118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      CopyValuesToItems(type, values, NameInfo(), app_locale, &name_);
4128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
4138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case EMAIL:
4158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      CopyValuesToItems(type, values, EmailInfo(), app_locale, &email_);
4168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
4178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case PHONE_HOME:
4198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case PHONE_BILLING:
4208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      CopyValuesToItems(
4218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com          type, values, PhoneNumber(this), app_locale, &phone_number_);
4228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
4238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    default:
4258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      if (values.size() == 1U) {
4268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        SetInfo(type, values[0], app_locale);
4278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      } else if (values.empty()) {
4288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        SetInfo(type, base::string16(), app_locale);
4298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      } else {
4308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        // Shouldn't attempt to set multiple values on single-valued field.
4318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        NOTREACHED();
4328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      }
4338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      break;
4348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
4358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
4368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comvoid AutofillProfile::GetMultiInfo(const AutofillType& type,
4388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                   const std::string& app_locale,
4398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                   std::vector<base::string16>* values) const {
4408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  GetMultiInfoImpl(type, app_locale, values);
4418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
4428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::IsEmpty(const std::string& app_locale) const {
4448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  ServerFieldTypeSet types;
4458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  GetNonEmptyTypes(app_locale, &types);
4468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return types.empty();
4478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
4488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::IsPresentButInvalid(ServerFieldType type) const {
4508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  std::string country = UTF16ToUTF8(GetRawInfo(ADDRESS_HOME_COUNTRY));
4518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  base::string16 data = GetRawInfo(type);
4528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  if (data.empty())
4538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return false;
4548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  switch (type) {
4568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case ADDRESS_HOME_STATE:
4578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return country == "US" && !autofill::IsValidState(data);
4588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case ADDRESS_HOME_ZIP:
4608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return country == "US" && !autofill::IsValidZip(data);
4618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case PHONE_HOME_WHOLE_NUMBER:
4638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return !i18n::PhoneObject(data, country).IsValidNumber();
4648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    case EMAIL_ADDRESS:
4668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return !autofill::IsValidEmailAddress(data);
4678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    default:
4698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      NOTREACHED();
4708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return false;
4718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
4728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
4738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comint AutofillProfile::Compare(const AutofillProfile& profile) const {
4758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  const ServerFieldType single_value_types[] = {
4768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    COMPANY_NAME,
4778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_STREET_ADDRESS,
4788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_DEPENDENT_LOCALITY,
4798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_CITY,
4808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_STATE,
4818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_ZIP,
4828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_SORTING_CODE,
4838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    ADDRESS_HOME_COUNTRY,
4848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  };
4858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < arraysize(single_value_types); ++i) {
4878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    int comparison = GetRawInfo(single_value_types[i]).compare(
4888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        profile.GetRawInfo(single_value_types[i]));
4898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (comparison != 0)
4908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return comparison;
4918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
4928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
4938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  const ServerFieldType multi_value_types[] = { NAME_FULL,
4948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                                NAME_FIRST,
4958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                                NAME_MIDDLE,
4968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                                NAME_LAST,
4978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                                EMAIL_ADDRESS,
4988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                                PHONE_HOME_WHOLE_NUMBER };
4998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  for (size_t i = 0; i < arraysize(multi_value_types); ++i) {
5018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    std::vector<base::string16> values_a;
5028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    std::vector<base::string16> values_b;
5038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    GetRawMultiInfo(multi_value_types[i], &values_a);
5048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    profile.GetRawMultiInfo(multi_value_types[i], &values_b);
5058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (values_a.size() < values_b.size())
5068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return -1;
5078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (values_a.size() > values_b.size())
5088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return 1;
5098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    for (size_t j = 0; j < values_a.size(); ++j) {
5108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      int comparison = values_a[j].compare(values_b[j]);
5118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      if (comparison != 0)
5128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        return comparison;
5138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    }
5148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
5158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return 0;
5178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
5188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::EqualsSansOrigin(const AutofillProfile& profile) const {
5208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return guid() == profile.guid() &&
5218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com         language_code() == profile.language_code() &&
5228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com         Compare(profile) == 0;
5238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
5248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::EqualsSansGuid(const AutofillProfile& profile) const {
5268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return origin() == profile.origin() &&
527cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com         language_code() == profile.language_code() &&
5288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com         Compare(profile) == 0;
5298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
530cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com
5318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::operator==(const AutofillProfile& profile) const {
5328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return guid() == profile.guid() && EqualsSansGuid(profile);
5338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
5348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::operator!=(const AutofillProfile& profile) const {
5368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return !operator==(profile);
5378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
5388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comconst base::string16 AutofillProfile::PrimaryValue() const {
5408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY);
5418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
5428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.combool AutofillProfile::IsSubsetOf(const AutofillProfile& profile,
5448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                                 const std::string& app_locale) const {
5458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  ServerFieldTypeSet types;
5468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  GetNonEmptyTypes(app_locale, &types);
5478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
548cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com  for (ServerFieldTypeSet::const_iterator it = types.begin(); it != types.end();
5498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com       ++it) {
5508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    if (*it == NAME_FULL || *it == ADDRESS_HOME_STREET_ADDRESS) {
551cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com      // Ignore the compound "full name" field type.  We are only interested in
5528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      // comparing the constituent parts.  For example, if |this| has a middle
5538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      // name saved, but |profile| lacks one, |profile| could still be a subset
5548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      // of |this|.  Likewise, ignore the compound "street address" type, as we
5558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      // are only interested in matching line-by-line.
5568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      continue;
5578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    } else if (AutofillType(*it).group() == PHONE_HOME) {
5588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      // Phone numbers should be canonicalized prior to being compared.
5598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      if (*it != PHONE_HOME_WHOLE_NUMBER) {
5608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        continue;
5618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      } else if (!i18n::PhoneNumbersMatch(
5628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            GetRawInfo(*it),
5638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            profile.GetRawInfo(*it),
5648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)),
5658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            app_locale)) {
5668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        return false;
5678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      }
5688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    } else if (base::StringToLowerASCII(GetRawInfo(*it)) !=
5698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com                   base::StringToLowerASCII(profile.GetRawInfo(*it))) {
5708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com      return false;
5718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    }
5728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  }
5738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
5748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com  return true;
575cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com}
576
577void AutofillProfile::OverwriteOrAppendNames(
578    const std::vector<NameInfo>& names,
579    const std::string& app_locale) {
580  std::vector<NameInfo> results(name_);
581  for (std::vector<NameInfo>::const_iterator it = names.begin();
582       it != names.end();
583       ++it) {
584    NameInfo imported_name = *it;
585    bool should_append_imported_name = true;
586
587    for (size_t index = 0; index < name_.size(); ++index) {
588      NameInfo current_name = name_[index];
589      if (current_name.ParsedNamesAreEqual(imported_name)) {
590        if (current_name.GetRawInfo(NAME_FULL).empty()) {
591          current_name.SetRawInfo(NAME_FULL,
592                                  imported_name.GetRawInfo(NAME_FULL));
593        }
594
595        should_append_imported_name = false;
596        break;
597      }
598
599      AutofillType type = AutofillType(NAME_FULL);
600      base::string16 full_name = current_name.GetInfo(type, app_locale);
601      if (base::StringToLowerASCII(full_name) ==
602          base::StringToLowerASCII(imported_name.GetInfo(type, app_locale))) {
603        // The imported name has the same full name string as one of the
604        // existing names for this profile.  Because full names are
605        // _heuristically_ parsed into {first, middle, last} name components,
606        // it's possible that either the existing name or the imported name
607        // was misparsed.  Prefer to keep the name whose {first, middle,
608        // last} components do not match those computed by the heuristic
609        // parse, as this more likely represents the correct, user-input parse
610        // of the name.
611        NameInfo heuristically_parsed_name;
612        heuristically_parsed_name.SetInfo(type, full_name, app_locale);
613        if (imported_name.ParsedNamesAreEqual(heuristically_parsed_name)) {
614          should_append_imported_name = false;
615          break;
616        }
617
618        if (current_name.ParsedNamesAreEqual(heuristically_parsed_name)) {
619          results[index] = imported_name;
620          should_append_imported_name = false;
621          break;
622        }
623      }
624    }
625
626    // Append unique names to the list.
627    if (should_append_imported_name)
628      results.push_back(imported_name);
629  }
630
631  name_.swap(results);
632}
633
634void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile,
635                                           const std::string& app_locale) {
636  // Verified profiles should never be overwritten with unverified data.
637  DCHECK(!IsVerified() || profile.IsVerified());
638  set_origin(profile.origin());
639  set_language_code(profile.language_code());
640
641  ServerFieldTypeSet field_types;
642  profile.GetNonEmptyTypes(app_locale, &field_types);
643
644  // Only transfer "full" types (e.g. full name) and not fragments (e.g.
645  // first name, last name).
646  CollapseCompoundFieldTypes(&field_types);
647
648  // TODO(isherman): Revisit this decision in the context of i18n and storing
649  // full addresses rather than storing 1-to-2 lines of an address.
650  // For addresses, do the opposite: transfer individual address lines, rather
651  // than full addresses.
652  field_types.erase(ADDRESS_HOME_STREET_ADDRESS);
653
654  for (ServerFieldTypeSet::const_iterator iter = field_types.begin();
655       iter != field_types.end(); ++iter) {
656    FieldTypeGroup group = AutofillType(*iter).group();
657    // Special case names.
658    if (group == NAME) {
659      OverwriteOrAppendNames(profile.name_, app_locale);
660      continue;
661    }
662
663    // Single value field --- overwrite.
664    if (!AutofillProfile::SupportsMultiValue(*iter)) {
665      base::string16 new_value = profile.GetRawInfo(*iter);
666      if (base::StringToLowerASCII(GetRawInfo(*iter)) !=
667              base::StringToLowerASCII(new_value)) {
668        SetRawInfo(*iter, new_value);
669      }
670      continue;
671    }
672
673    // Multi value field --- overwrite/append.
674    std::vector<base::string16> new_values;
675    profile.GetRawMultiInfo(*iter, &new_values);
676    std::vector<base::string16> existing_values;
677    GetRawMultiInfo(*iter, &existing_values);
678
679    // GetMultiInfo always returns at least one element, even if the profile
680    // has no data stored for this field type.
681    if (existing_values.size() == 1 && existing_values.front().empty())
682      existing_values.clear();
683
684    for (std::vector<base::string16>::iterator value_iter =
685             new_values.begin();
686         value_iter != new_values.end(); ++value_iter) {
687      // Don't add duplicates. Most types get case insensitive matching.
688      std::vector<base::string16>::const_iterator existing_iter;
689
690      if (group == PHONE_HOME) {
691        // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377",
692        // "(800)356-9377" and "356-9377" are considered the same.
693        std::string country_code =
694            base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
695        existing_iter =
696            std::find_if(existing_values.begin(), existing_values.end(),
697                         FindByPhone(*value_iter, country_code, app_locale));
698      } else {
699        existing_iter =
700            std::find_if(existing_values.begin(), existing_values.end(),
701                         CaseInsensitiveStringEquals(*value_iter));
702      }
703
704      if (existing_iter == existing_values.end())
705        existing_values.insert(existing_values.end(), *value_iter);
706    }
707
708    SetRawMultiInfo(*iter, existing_values);
709  }
710}
711
712// static
713bool AutofillProfile::SupportsMultiValue(ServerFieldType type) {
714  FieldTypeGroup group = AutofillType(type).group();
715  return group == NAME ||
716         group == NAME_BILLING ||
717         group == EMAIL ||
718         group == PHONE_HOME ||
719         group == PHONE_BILLING;
720}
721
722// static
723void AutofillProfile::CreateDifferentiatingLabels(
724    const std::vector<AutofillProfile*>& profiles,
725    const std::string& app_locale,
726    std::vector<base::string16>* labels) {
727  const size_t kMinimalFieldsShown = 2;
728  CreateInferredLabels(profiles, NULL, UNKNOWN_TYPE, kMinimalFieldsShown,
729                       app_locale, labels);
730  DCHECK_EQ(profiles.size(), labels->size());
731}
732
733// static
734void AutofillProfile::CreateInferredLabels(
735    const std::vector<AutofillProfile*>& profiles,
736    const std::vector<ServerFieldType>* suggested_fields,
737    ServerFieldType excluded_field,
738    size_t minimal_fields_shown,
739    const std::string& app_locale,
740    std::vector<base::string16>* labels) {
741  std::vector<ServerFieldType> fields_to_use;
742  GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field,
743                                     &fields_to_use);
744
745  // Construct the default label for each profile. Also construct a map that
746  // associates each label with the profiles that have this label. This map is
747  // then used to detect which labels need further differentiating fields.
748  std::map<base::string16, std::list<size_t> > labels_to_profiles;
749  for (size_t i = 0; i < profiles.size(); ++i) {
750    base::string16 label =
751        profiles[i]->ConstructInferredLabel(fields_to_use,
752                                            minimal_fields_shown,
753                                            app_locale);
754    labels_to_profiles[label].push_back(i);
755  }
756
757  labels->resize(profiles.size());
758  for (std::map<base::string16, std::list<size_t> >::const_iterator it =
759           labels_to_profiles.begin();
760       it != labels_to_profiles.end(); ++it) {
761    if (it->second.size() == 1) {
762      // This label is unique, so use it without any further ado.
763      base::string16 label = it->first;
764      size_t profile_index = it->second.front();
765      (*labels)[profile_index] = label;
766    } else {
767      // We have more than one profile with the same label, so add
768      // differentiating fields.
769      CreateInferredLabelsHelper(profiles, it->second, fields_to_use,
770                                 minimal_fields_shown, app_locale, labels);
771    }
772  }
773}
774
775void AutofillProfile::GetSupportedTypes(
776    ServerFieldTypeSet* supported_types) const {
777  FormGroupList info = FormGroups();
778  for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
779    (*it)->GetSupportedTypes(supported_types);
780}
781
782void AutofillProfile::GetMultiInfoImpl(
783    const AutofillType& type,
784    const std::string& app_locale,
785    std::vector<base::string16>* values) const {
786  switch (type.group()) {
787    case NAME:
788    case NAME_BILLING:
789      CopyItemsToValues(type, name_, app_locale, values);
790      break;
791    case EMAIL:
792      CopyItemsToValues(type, email_, app_locale, values);
793      break;
794    case PHONE_HOME:
795    case PHONE_BILLING:
796      CopyItemsToValues(type, phone_number_, app_locale, values);
797      break;
798    default:
799      values->resize(1);
800      (*values)[0] = GetFormGroupInfo(*this, type, app_locale);
801  }
802}
803
804base::string16 AutofillProfile::ConstructInferredLabel(
805    const std::vector<ServerFieldType>& included_fields,
806    size_t num_fields_to_use,
807    const std::string& app_locale) const {
808  base::string16 separator =
809      l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
810
811  AutofillType region_code_type(HTML_TYPE_COUNTRY_CODE, HTML_MODE_NONE);
812  const base::string16& profile_region_code =
813      GetInfo(region_code_type, app_locale);
814  std::string address_region_code = UTF16ToUTF8(profile_region_code);
815
816  // A copy of |this| pruned down to contain only data for the address fields in
817  // |included_fields|.
818  AutofillProfile trimmed_profile(guid(), origin());
819  trimmed_profile.SetInfo(region_code_type, profile_region_code, app_locale);
820  trimmed_profile.set_language_code(language_code());
821
822  std::vector<ServerFieldType> remaining_fields;
823  for (std::vector<ServerFieldType>::const_iterator it =
824           included_fields.begin();
825       it != included_fields.end() && num_fields_to_use > 0;
826       ++it) {
827    AddressField address_field;
828    if (!i18n::FieldForType(*it, &address_field) ||
829        !::i18n::addressinput::IsFieldUsed(
830            address_field, address_region_code) ||
831        address_field == ::i18n::addressinput::COUNTRY) {
832      remaining_fields.push_back(*it);
833      continue;
834    }
835
836    AutofillType autofill_type(*it);
837    const base::string16& field_value = GetInfo(autofill_type, app_locale);
838    if (field_value.empty())
839      continue;
840
841    trimmed_profile.SetInfo(autofill_type, field_value, app_locale);
842    --num_fields_to_use;
843  }
844
845  scoped_ptr<AddressData> address_data =
846      i18n::CreateAddressDataFromAutofillProfile(trimmed_profile, app_locale);
847  std::string address_line;
848  ::i18n::addressinput::GetFormattedNationalAddressLine(
849      *address_data, &address_line);
850  base::string16 label = base::UTF8ToUTF16(address_line);
851
852  for (std::vector<ServerFieldType>::const_iterator it =
853           remaining_fields.begin();
854       it != remaining_fields.end() && num_fields_to_use > 0;
855       ++it) {
856    const base::string16& field_value = GetInfo(AutofillType(*it), app_locale);
857    if (field_value.empty())
858      continue;
859
860    if (!label.empty())
861      label.append(separator);
862
863    label.append(field_value);
864    --num_fields_to_use;
865  }
866
867  // If country code is missing, libaddressinput won't be used to format the
868  // address. In this case the suggestion might include a multi-line street
869  // address which needs to be flattened.
870  base::ReplaceChars(label, base::ASCIIToUTF16("\n"), separator, &label);
871
872  return label;
873}
874
875// static
876void AutofillProfile::CreateInferredLabelsHelper(
877    const std::vector<AutofillProfile*>& profiles,
878    const std::list<size_t>& indices,
879    const std::vector<ServerFieldType>& fields,
880    size_t num_fields_to_include,
881    const std::string& app_locale,
882    std::vector<base::string16>* labels) {
883  // For efficiency, we first construct a map of fields to their text values and
884  // each value's frequency.
885  std::map<ServerFieldType,
886           std::map<base::string16, size_t> > field_text_frequencies_by_field;
887  for (std::vector<ServerFieldType>::const_iterator field = fields.begin();
888       field != fields.end(); ++field) {
889    std::map<base::string16, size_t>& field_text_frequencies =
890        field_text_frequencies_by_field[*field];
891
892    for (std::list<size_t>::const_iterator it = indices.begin();
893         it != indices.end(); ++it) {
894      const AutofillProfile* profile = profiles[*it];
895      base::string16 field_text =
896          profile->GetInfo(AutofillType(*field), app_locale);
897
898      // If this label is not already in the map, add it with frequency 0.
899      if (!field_text_frequencies.count(field_text))
900        field_text_frequencies[field_text] = 0;
901
902      // Now, increment the frequency for this label.
903      ++field_text_frequencies[field_text];
904    }
905  }
906
907  // Now comes the meat of the algorithm. For each profile, we scan the list of
908  // fields to use, looking for two things:
909  //  1. A (non-empty) field that differentiates the profile from all others
910  //  2. At least |num_fields_to_include| non-empty fields
911  // Before we've satisfied condition (2), we include all fields, even ones that
912  // are identical across all the profiles. Once we've satisfied condition (2),
913  // we only include fields that that have at last two distinct values.
914  for (std::list<size_t>::const_iterator it = indices.begin();
915       it != indices.end(); ++it) {
916    const AutofillProfile* profile = profiles[*it];
917
918    std::vector<ServerFieldType> label_fields;
919    bool found_differentiating_field = false;
920    for (std::vector<ServerFieldType>::const_iterator field = fields.begin();
921         field != fields.end(); ++field) {
922      // Skip over empty fields.
923      base::string16 field_text =
924          profile->GetInfo(AutofillType(*field), app_locale);
925      if (field_text.empty())
926        continue;
927
928      std::map<base::string16, size_t>& field_text_frequencies =
929          field_text_frequencies_by_field[*field];
930      found_differentiating_field |=
931          !field_text_frequencies.count(base::string16()) &&
932          (field_text_frequencies[field_text] == 1);
933
934      // Once we've found enough non-empty fields, skip over any remaining
935      // fields that are identical across all the profiles.
936      if (label_fields.size() >= num_fields_to_include &&
937          (field_text_frequencies.size() == 1))
938        continue;
939
940      label_fields.push_back(*field);
941
942      // If we've (1) found a differentiating field and (2) found at least
943      // |num_fields_to_include| non-empty fields, we're done!
944      if (found_differentiating_field &&
945          label_fields.size() >= num_fields_to_include)
946        break;
947    }
948
949    (*labels)[*it] = profile->ConstructInferredLabel(
950        label_fields, label_fields.size(), app_locale);
951  }
952}
953
954AutofillProfile::FormGroupList AutofillProfile::FormGroups() const {
955  FormGroupList v(5);
956  v[0] = &name_[0];
957  v[1] = &email_[0];
958  v[2] = &company_;
959  v[3] = &phone_number_[0];
960  v[4] = &address_;
961  return v;
962}
963
964const FormGroup* AutofillProfile::FormGroupForType(
965    const AutofillType& type) const {
966  return const_cast<AutofillProfile*>(this)->MutableFormGroupForType(type);
967}
968
969FormGroup* AutofillProfile::MutableFormGroupForType(const AutofillType& type) {
970  switch (type.group()) {
971    case NAME:
972    case NAME_BILLING:
973      return &name_[0];
974
975    case EMAIL:
976      return &email_[0];
977
978    case COMPANY:
979      return &company_;
980
981    case PHONE_HOME:
982    case PHONE_BILLING:
983      return &phone_number_[0];
984
985    case ADDRESS_HOME:
986    case ADDRESS_BILLING:
987      return &address_;
988
989    case NO_GROUP:
990    case CREDIT_CARD:
991    case PASSWORD_FIELD:
992    case TRANSACTION:
993        return NULL;
994  }
995
996  NOTREACHED();
997  return NULL;
998}
999
1000// So we can compare AutofillProfiles with EXPECT_EQ().
1001std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
1002  return os
1003      << profile.guid()
1004      << " "
1005      << profile.origin()
1006      << " "
1007      << UTF16ToUTF8(MultiString(profile, NAME_FIRST))
1008      << " "
1009      << UTF16ToUTF8(MultiString(profile, NAME_MIDDLE))
1010      << " "
1011      << UTF16ToUTF8(MultiString(profile, NAME_LAST))
1012      << " "
1013      << UTF16ToUTF8(MultiString(profile, EMAIL_ADDRESS))
1014      << " "
1015      << UTF16ToUTF8(profile.GetRawInfo(COMPANY_NAME))
1016      << " "
1017      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE1))
1018      << " "
1019      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE2))
1020      << " "
1021      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))
1022      << " "
1023      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY))
1024      << " "
1025      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE))
1026      << " "
1027      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP))
1028      << " "
1029      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE))
1030      << " "
1031      << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))
1032      << " "
1033      << profile.language_code()
1034      << " "
1035      << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER));
1036}
1037
1038}  // namespace autofill
1039