Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(742)

Side by Side Diff: components/autofill/core/browser/personal_data_manager.cc

Issue 22009003: [Autofill] Distinguish between native field types and potentially HTML field types. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/personal_data_manager.h" 5 #include "components/autofill/core/browser/personal_data_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <iterator> 9 #include <iterator>
10 10
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 return false; 102 return false;
103 103
104 if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty()) 104 if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty())
105 return false; 105 return false;
106 106
107 return true; 107 return true;
108 } 108 }
109 109
110 // Return true if the |field_type| and |value| are valid within the context 110 // Return true if the |field_type| and |value| are valid within the context
111 // of importing a form. 111 // of importing a form.
112 bool IsValidFieldTypeAndValue(const std::set<AutofillFieldType>& types_seen, 112 bool IsValidFieldTypeAndValue(const std::set<ServerFieldType>& types_seen,
113 AutofillFieldType field_type, 113 ServerFieldType field_type,
114 const base::string16& value) { 114 const base::string16& value) {
115 // Abandon the import if two fields of the same type are encountered. 115 // Abandon the import if two fields of the same type are encountered.
116 // This indicates ambiguous data or miscategorization of types. 116 // This indicates ambiguous data or miscategorization of types.
117 // Make an exception for PHONE_HOME_NUMBER however as both prefix and 117 // Make an exception for PHONE_HOME_NUMBER however as both prefix and
118 // suffix are stored against this type, and for EMAIL_ADDRESS because it is 118 // suffix are stored against this type, and for EMAIL_ADDRESS because it is
119 // common to see second 'confirm email address' fields on forms. 119 // common to see second 'confirm email address' fields on forms.
120 if (types_seen.count(field_type) && field_type != PHONE_HOME_NUMBER && 120 if (types_seen.count(field_type) &&
121 field_type != PHONE_HOME_NUMBER &&
121 field_type != EMAIL_ADDRESS) 122 field_type != EMAIL_ADDRESS)
122 return false; 123 return false;
123 124
124 // Abandon the import if an email address value shows up in a field that is 125 // Abandon the import if an email address value shows up in a field that is
125 // not an email address. 126 // not an email address.
126 if (field_type != EMAIL_ADDRESS && autofill::IsValidEmailAddress(value)) 127 if (field_type != EMAIL_ADDRESS && IsValidEmailAddress(value))
127 return false; 128 return false;
128 129
129 return true; 130 return true;
130 } 131 }
131 132
132 } // namespace 133 } // namespace
133 134
134 PersonalDataManager::PersonalDataManager(const std::string& app_locale) 135 PersonalDataManager::PersonalDataManager(const std::string& app_locale)
135 : browser_context_(NULL), 136 : browser_context_(NULL),
136 is_data_loaded_(false), 137 is_data_loaded_(false),
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 234
234 const std::string origin = form.source_url().spec(); 235 const std::string origin = form.source_url().spec();
235 imported_profile->set_origin(origin); 236 imported_profile->set_origin(origin);
236 local_imported_credit_card->set_origin(origin); 237 local_imported_credit_card->set_origin(origin);
237 238
238 // Parse the form and construct a profile based on the information that is 239 // Parse the form and construct a profile based on the information that is
239 // possible to import. 240 // possible to import.
240 int importable_credit_card_fields = 0; 241 int importable_credit_card_fields = 0;
241 242
242 // Detect and discard forms with multiple fields of the same type. 243 // Detect and discard forms with multiple fields of the same type.
243 std::set<AutofillFieldType> types_seen; 244 // TODO(isherman): Some types are overlapping but not equal, e.g. phone number
245 // parts, address parts.
246 std::set<ServerFieldType> types_seen;
244 247
245 // We only set complete phone, so aggregate phone parts in these vars and set 248 // We only set complete phone, so aggregate phone parts in these vars and set
246 // complete at the end. 249 // complete at the end.
247 PhoneNumber::PhoneCombineHelper home; 250 PhoneNumber::PhoneCombineHelper home;
248 251
249 for (size_t i = 0; i < form.field_count(); ++i) { 252 for (size_t i = 0; i < form.field_count(); ++i) {
250 const AutofillField* field = form.field(i); 253 const AutofillField* field = form.field(i);
251 base::string16 value = CollapseWhitespace(field->value, false); 254 base::string16 value = CollapseWhitespace(field->value, false);
252 255
253 // If we don't know the type of the field, or the user hasn't entered any 256 // If we don't know the type of the field, or the user hasn't entered any
254 // information into the field, then skip it. 257 // information into the field, then skip it.
255 if (!field->IsFieldFillable() || value.empty()) 258 if (!field->IsFieldFillable() || value.empty())
256 continue; 259 continue;
257 260
258 AutofillFieldType field_type = field->type(); 261 AutofillType field_type = field->Type();
259 FieldTypeGroup group(AutofillType(field_type).group()); 262 ServerFieldType server_field_type = field_type.server_type();
263 FieldTypeGroup group(field_type.group());
260 264
261 // There can be multiple email fields (e.g. in the case of 'confirm email' 265 // There can be multiple email fields (e.g. in the case of 'confirm email'
262 // fields) but they must all contain the same value, else the profile is 266 // fields) but they must all contain the same value, else the profile is
263 // invalid. 267 // invalid.
264 if (field_type == EMAIL_ADDRESS) { 268 if (server_field_type == EMAIL_ADDRESS) {
265 if (types_seen.count(field_type) && 269 if (types_seen.count(server_field_type) &&
266 imported_profile->GetRawInfo(field_type) != value) { 270 imported_profile->GetRawInfo(EMAIL_ADDRESS) != value) {
267 imported_profile.reset(); 271 imported_profile.reset();
268 break; 272 break;
269 } 273 }
270 } 274 }
271 275
272 // If the |field_type| and |value| don't pass basic validity checks then 276 // If the |field_type| and |value| don't pass basic validity checks then
273 // abandon the import. 277 // abandon the import.
274 if (!IsValidFieldTypeAndValue(types_seen, field_type, value)) { 278 if (!IsValidFieldTypeAndValue(types_seen, server_field_type, value)) {
275 imported_profile.reset(); 279 imported_profile.reset();
276 local_imported_credit_card.reset(); 280 local_imported_credit_card.reset();
277 break; 281 break;
278 } 282 }
279 283
280 types_seen.insert(field_type); 284 types_seen.insert(server_field_type);
281 285
282 if (group == CREDIT_CARD) { 286 if (group == CREDIT_CARD) {
283 if (LowerCaseEqualsASCII(field->form_control_type, "month")) { 287 if (LowerCaseEqualsASCII(field->form_control_type, "month")) {
284 DCHECK_EQ(CREDIT_CARD_EXP_MONTH, field_type); 288 DCHECK_EQ(CREDIT_CARD_EXP_MONTH, server_field_type);
285 local_imported_credit_card->SetInfoForMonthInputType(value); 289 local_imported_credit_card->SetInfoForMonthInputType(value);
286 } else { 290 } else {
287 local_imported_credit_card->SetInfo(field_type, value, app_locale_); 291 local_imported_credit_card->SetInfo(field_type, value, app_locale_);
288 } 292 }
289 ++importable_credit_card_fields; 293 ++importable_credit_card_fields;
290 } else { 294 } else {
291 // We need to store phone data in the variables, before building the whole 295 // We need to store phone data in the variables, before building the whole
292 // number at the end. The rest of the fields are set "as is". 296 // number at the end. The rest of the fields are set "as is".
293 // If the fields are not the phone fields in question home.SetInfo() is 297 // If the fields are not the phone fields in question home.SetInfo() is
294 // going to return false. 298 // going to return false.
295 if (!home.SetInfo(field_type, value)) 299 if (!home.SetInfo(field_type, value))
296 imported_profile->SetInfo(field_type, value, app_locale_); 300 imported_profile->SetInfo(field_type, value, app_locale_);
297 301
298 // Reject profiles with invalid country information. 302 // Reject profiles with invalid country information.
299 if (field_type == ADDRESS_HOME_COUNTRY && 303 if (server_field_type == ADDRESS_HOME_COUNTRY &&
300 !value.empty() && 304 !value.empty() &&
301 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { 305 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) {
302 imported_profile.reset(); 306 imported_profile.reset();
303 break; 307 break;
304 } 308 }
305 } 309 }
306 } 310 }
307 311
308 // Construct the phone number. Reject the profile if the number is invalid. 312 // Construct the phone number. Reject the profile if the number is invalid.
309 if (imported_profile.get() && !home.IsEmpty()) { 313 if (imported_profile.get() && !home.IsEmpty()) {
310 base::string16 constructed_number; 314 base::string16 constructed_number;
311 if (!home.ParseNumber(*imported_profile, app_locale_, 315 if (!home.ParseNumber(*imported_profile, app_locale_,
312 &constructed_number) || 316 &constructed_number) ||
313 !imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number, 317 !imported_profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
318 constructed_number,
314 app_locale_)) { 319 app_locale_)) {
315 imported_profile.reset(); 320 imported_profile.reset();
316 } 321 }
317 } 322 }
318 323
319 // Reject the profile if minimum address and validation requirements are not 324 // Reject the profile if minimum address and validation requirements are not
320 // met. 325 // met.
321 if (imported_profile.get() && 326 if (imported_profile.get() &&
322 !IsValidLearnableProfile(*imported_profile, app_locale_)) 327 !IsValidLearnableProfile(*imported_profile, app_locale_))
323 imported_profile.reset(); 328 imported_profile.reset();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); 519 const std::vector<CreditCard*>& credit_cards = GetCreditCards();
515 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); 520 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
516 iter != credit_cards.end(); ++iter) { 521 iter != credit_cards.end(); ++iter) {
517 if ((*iter)->guid() == guid) 522 if ((*iter)->guid() == guid)
518 return *iter; 523 return *iter;
519 } 524 }
520 return NULL; 525 return NULL;
521 } 526 }
522 527
523 void PersonalDataManager::GetNonEmptyTypes( 528 void PersonalDataManager::GetNonEmptyTypes(
524 FieldTypeSet* non_empty_types) { 529 ServerFieldTypeSet* non_empty_types) {
525 const std::vector<AutofillProfile*>& profiles = GetProfiles(); 530 const std::vector<AutofillProfile*>& profiles = GetProfiles();
526 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); 531 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
527 iter != profiles.end(); ++iter) { 532 iter != profiles.end(); ++iter) {
528 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); 533 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
529 } 534 }
530 535
531 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin(); 536 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin();
532 iter != credit_cards_.end(); ++iter) { 537 iter != credit_cards_.end(); ++iter) {
533 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); 538 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
534 } 539 }
(...skipping 27 matching lines...) Expand all
562 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { 567 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
563 return credit_cards_.get(); 568 return credit_cards_.get();
564 } 569 }
565 570
566 void PersonalDataManager::Refresh() { 571 void PersonalDataManager::Refresh() {
567 LoadProfiles(); 572 LoadProfiles();
568 LoadCreditCards(); 573 LoadCreditCards();
569 } 574 }
570 575
571 void PersonalDataManager::GetProfileSuggestions( 576 void PersonalDataManager::GetProfileSuggestions(
572 AutofillFieldType type, 577 const AutofillType& type,
573 const base::string16& field_contents, 578 const base::string16& field_contents,
574 bool field_is_autofilled, 579 bool field_is_autofilled,
575 std::vector<AutofillFieldType> other_field_types, 580 std::vector<ServerFieldType> other_field_types,
576 std::vector<base::string16>* values, 581 std::vector<base::string16>* values,
577 std::vector<base::string16>* labels, 582 std::vector<base::string16>* labels,
578 std::vector<base::string16>* icons, 583 std::vector<base::string16>* icons,
579 std::vector<GUIDPair>* guid_pairs) { 584 std::vector<GUIDPair>* guid_pairs) {
580 values->clear(); 585 values->clear();
581 labels->clear(); 586 labels->clear();
582 icons->clear(); 587 icons->clear();
583 guid_pairs->clear(); 588 guid_pairs->clear();
584 589
585 const std::vector<AutofillProfile*>& profiles = GetProfiles(); 590 const std::vector<AutofillProfile*>& profiles = GetProfiles();
(...skipping 19 matching lines...) Expand all
605 if (multi_values[i].empty()) 610 if (multi_values[i].empty())
606 continue; 611 continue;
607 612
608 base::string16 profile_value_lower_case( 613 base::string16 profile_value_lower_case(
609 StringToLowerASCII(multi_values[i])); 614 StringToLowerASCII(multi_values[i]));
610 base::string16 field_value_lower_case( 615 base::string16 field_value_lower_case(
611 StringToLowerASCII(field_contents)); 616 StringToLowerASCII(field_contents));
612 // Phone numbers could be split in US forms, so field value could be 617 // Phone numbers could be split in US forms, so field value could be
613 // either prefix or suffix of the phone. 618 // either prefix or suffix of the phone.
614 bool matched_phones = false; 619 bool matched_phones = false;
615 if (type == PHONE_HOME_NUMBER && !field_value_lower_case.empty() && 620 if ((type.server_type() == PHONE_HOME_NUMBER ||
616 (profile_value_lower_case.find(field_value_lower_case) != 621 type.server_type() == PHONE_BILLING_NUMBER) &&
617 base::string16::npos)) { 622 !field_value_lower_case.empty() &&
623 profile_value_lower_case.find(field_value_lower_case) !=
624 base::string16::npos) {
618 matched_phones = true; 625 matched_phones = true;
619 } 626 }
620 627
621 // Suggest variants of the profile that's already been filled in. 628 // Suggest variants of the profile that's already been filled in.
622 if (matched_phones || 629 if (matched_phones ||
623 profile_value_lower_case == field_value_lower_case) { 630 profile_value_lower_case == field_value_lower_case) {
624 for (size_t j = 0; j < multi_values.size(); ++j) { 631 for (size_t j = 0; j < multi_values.size(); ++j) {
625 if (!multi_values[j].empty()) { 632 if (!multi_values[j].empty()) {
626 values->push_back(multi_values[j]); 633 values->push_back(multi_values[j]);
627 guid_pairs->push_back(GUIDPair(profile->guid(), j)); 634 guid_pairs->push_back(GUIDPair(profile->guid(), j));
628 } 635 }
629 } 636 }
630 637
631 // We've added all the values for this profile so move on to the 638 // We've added all the values for this profile so move on to the
632 // next. 639 // next.
633 break; 640 break;
634 } 641 }
635 } 642 }
636 } 643 }
637 } 644 }
638 645
639 if (!field_is_autofilled) { 646 if (!field_is_autofilled) {
640 AutofillProfile::CreateInferredLabels( 647 AutofillProfile::CreateInferredLabels(
641 &matched_profiles, &other_field_types, 648 &matched_profiles, &other_field_types,
642 type, 1, labels); 649 type.server_type(), 1, labels);
643 } else { 650 } else {
644 // No sub-labels for previously filled fields. 651 // No sub-labels for previously filled fields.
645 labels->resize(values->size()); 652 labels->resize(values->size());
646 } 653 }
647 654
648 // No icons for profile suggestions. 655 // No icons for profile suggestions.
649 icons->resize(values->size()); 656 icons->resize(values->size());
650 } 657 }
651 658
652 void PersonalDataManager::GetCreditCardSuggestions( 659 void PersonalDataManager::GetCreditCardSuggestions(
653 AutofillFieldType type, 660 const AutofillType& type,
654 const base::string16& field_contents, 661 const base::string16& field_contents,
655 std::vector<base::string16>* values, 662 std::vector<base::string16>* values,
656 std::vector<base::string16>* labels, 663 std::vector<base::string16>* labels,
657 std::vector<base::string16>* icons, 664 std::vector<base::string16>* icons,
658 std::vector<GUIDPair>* guid_pairs) { 665 std::vector<GUIDPair>* guid_pairs) {
659 values->clear(); 666 values->clear();
660 labels->clear(); 667 labels->clear();
661 icons->clear(); 668 icons->clear();
662 guid_pairs->clear(); 669 guid_pairs->clear();
663 670
664 const std::vector<CreditCard*>& credit_cards = GetCreditCards(); 671 const std::vector<CreditCard*>& credit_cards = GetCreditCards();
665 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); 672 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
666 iter != credit_cards.end(); ++iter) { 673 iter != credit_cards.end(); ++iter) {
667 CreditCard* credit_card = *iter; 674 CreditCard* credit_card = *iter;
668 675
669 // The value of the stored data for this field type in the |credit_card|. 676 // The value of the stored data for this field type in the |credit_card|.
670 base::string16 creditcard_field_value = 677 base::string16 creditcard_field_value =
671 credit_card->GetInfo(type, app_locale_); 678 credit_card->GetInfo(type, app_locale_);
672 if (!creditcard_field_value.empty() && 679 if (!creditcard_field_value.empty() &&
673 StartsWith(creditcard_field_value, field_contents, false)) { 680 StartsWith(creditcard_field_value, field_contents, false)) {
674 if (type == CREDIT_CARD_NUMBER) 681 if (type.server_type() == CREDIT_CARD_NUMBER)
675 creditcard_field_value = credit_card->ObfuscatedNumber(); 682 creditcard_field_value = credit_card->ObfuscatedNumber();
676 683
677 base::string16 label; 684 base::string16 label;
678 if (credit_card->number().empty()) { 685 if (credit_card->number().empty()) {
679 // If there is no CC number, return name to show something. 686 // If there is no CC number, return name to show something.
680 label = credit_card->GetInfo(CREDIT_CARD_NAME, app_locale_); 687 label =
688 credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_);
681 } else { 689 } else {
682 label = kCreditCardPrefix; 690 label = kCreditCardPrefix;
683 label.append(credit_card->LastFourDigits()); 691 label.append(credit_card->LastFourDigits());
684 } 692 }
685 693
686 values->push_back(creditcard_field_value); 694 values->push_back(creditcard_field_value);
687 labels->push_back(label); 695 labels->push_back(label);
688 icons->push_back(UTF8ToUTF16(credit_card->type())); 696 icons->push_back(UTF8ToUTF16(credit_card->type()));
689 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); 697 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0));
690 } 698 }
691 } 699 }
692 } 700 }
693 701
694 bool PersonalDataManager::IsAutofillEnabled() const { 702 bool PersonalDataManager::IsAutofillEnabled() const {
695 return user_prefs::UserPrefs::Get(browser_context_)->GetBoolean( 703 return user_prefs::UserPrefs::Get(browser_context_)->GetBoolean(
696 prefs::kAutofillEnabled); 704 prefs::kAutofillEnabled);
697 } 705 }
698 706
699 // static 707 // static
700 bool PersonalDataManager::IsValidLearnableProfile( 708 bool PersonalDataManager::IsValidLearnableProfile(
701 const AutofillProfile& profile, 709 const AutofillProfile& profile,
702 const std::string& app_locale) { 710 const std::string& app_locale) {
703 if (!IsMinimumAddress(profile, app_locale)) 711 if (!IsMinimumAddress(profile, app_locale))
704 return false; 712 return false;
705 713
706 base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS); 714 base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS);
707 if (!email.empty() && !autofill::IsValidEmailAddress(email)) 715 if (!email.empty() && !IsValidEmailAddress(email))
708 return false; 716 return false;
709 717
710 // Reject profiles with invalid US state information. 718 // Reject profiles with invalid US state information.
711 if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE)) 719 if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE))
712 return false; 720 return false;
713 721
714 // Reject profiles with invalid US zip information. 722 // Reject profiles with invalid US zip information.
715 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP)) 723 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP))
716 return false; 724 return false;
717 725
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 const AutofillMetrics* metric_logger) { 1025 const AutofillMetrics* metric_logger) {
1018 metric_logger_.reset(metric_logger); 1026 metric_logger_.reset(metric_logger);
1019 } 1027 }
1020 1028
1021 void PersonalDataManager::set_browser_context( 1029 void PersonalDataManager::set_browser_context(
1022 content::BrowserContext* context) { 1030 content::BrowserContext* context) {
1023 browser_context_ = context; 1031 browser_context_ = context;
1024 } 1032 }
1025 1033
1026 } // namespace autofill 1034 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698