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