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