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