| 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 |