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> |
11 #include <set> | 11 #include <set> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
14 #include "base/guid.h" | 14 #include "base/guid.h" |
15 #include "base/i18n/case_conversion.h" | 15 #include "base/i18n/case_conversion.h" |
16 #include "base/i18n/char_iterator.h" | 16 #include "base/i18n/char_iterator.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
19 #include "base/sha1.h" | 19 #include "base/sha1.h" |
20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
21 #include "base/strings/utf_string_conversion_utils.h" | 21 #include "base/strings/utf_string_conversion_utils.h" |
22 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
23 #include "components/autofill/core/browser/address.h" | 23 #include "components/autofill/core/browser/address.h" |
24 #include "components/autofill/core/browser/address_i18n.h" | 24 #include "components/autofill/core/browser/address_i18n.h" |
25 #include "components/autofill/core/browser/autofill_country.h" | 25 #include "components/autofill/core/browser/autofill_country.h" |
26 #include "components/autofill/core/browser/autofill_field.h" | 26 #include "components/autofill/core/browser/autofill_field.h" |
| 27 #include "components/autofill/core/browser/autofill_metrics.h" |
27 #include "components/autofill/core/browser/autofill_type.h" | 28 #include "components/autofill/core/browser/autofill_type.h" |
28 #include "components/autofill/core/browser/contact_info.h" | 29 #include "components/autofill/core/browser/contact_info.h" |
29 #include "components/autofill/core/browser/phone_number.h" | 30 #include "components/autofill/core/browser/phone_number.h" |
30 #include "components/autofill/core/browser/phone_number_i18n.h" | 31 #include "components/autofill/core/browser/phone_number_i18n.h" |
31 #include "components/autofill/core/browser/state_names.h" | 32 #include "components/autofill/core/browser/state_names.h" |
32 #include "components/autofill/core/browser/validation.h" | 33 #include "components/autofill/core/browser/validation.h" |
33 #include "components/autofill/core/common/autofill_l10n_util.h" | 34 #include "components/autofill/core/common/autofill_l10n_util.h" |
34 #include "components/autofill/core/common/form_field_data.h" | 35 #include "components/autofill/core/common/form_field_data.h" |
35 #include "grit/components_strings.h" | 36 #include "grit/components_strings.h" |
36 #include "third_party/icu/source/common/unicode/uchar.h" | 37 #include "third_party/icu/source/common/unicode/uchar.h" |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 if (!compare) | 472 if (!compare) |
472 compare.reset(new l10n::CaseInsensitiveCompare()); | 473 compare.reset(new l10n::CaseInsensitiveCompare()); |
473 if (!compare->StringsEqual(value, profile.GetRawInfo(type))) | 474 if (!compare->StringsEqual(value, profile.GetRawInfo(type))) |
474 return false; | 475 return false; |
475 } | 476 } |
476 } | 477 } |
477 | 478 |
478 return true; | 479 return true; |
479 } | 480 } |
480 | 481 |
481 void AutofillProfile::OverwriteName(const NameInfo& imported_name, | 482 bool AutofillProfile::OverwriteName(const NameInfo& imported_name, |
482 const std::string& app_locale) { | 483 const std::string& app_locale) { |
483 if (name_.ParsedNamesAreEqual(imported_name)) { | 484 if (name_.ParsedNamesAreEqual(imported_name)) { |
484 if (name_.GetRawInfo(NAME_FULL).empty()) | 485 if (name_.GetRawInfo(NAME_FULL).empty() && |
| 486 !imported_name.GetRawInfo(NAME_FULL).empty()) { |
485 name_.SetRawInfo(NAME_FULL, imported_name.GetRawInfo(NAME_FULL)); | 487 name_.SetRawInfo(NAME_FULL, imported_name.GetRawInfo(NAME_FULL)); |
486 return; | 488 return true; |
| 489 } |
| 490 return false; |
487 } | 491 } |
488 | 492 |
489 l10n::CaseInsensitiveCompare compare; | 493 l10n::CaseInsensitiveCompare compare; |
490 AutofillType type = AutofillType(NAME_FULL); | 494 AutofillType type = AutofillType(NAME_FULL); |
491 base::string16 full_name = name_.GetInfo(type, app_locale); | 495 base::string16 full_name = name_.GetInfo(type, app_locale); |
492 if (compare.StringsEqual(full_name, | 496 if (compare.StringsEqual(full_name, |
493 imported_name.GetInfo(type, app_locale))) { | 497 imported_name.GetInfo(type, app_locale))) { |
494 // The imported name has the same full name string as the name for this | 498 // The imported name has the same full name string as the name for this |
495 // profile. Because full names are _heuristically_ parsed into | 499 // profile. Because full names are _heuristically_ parsed into |
496 // {first, middle, last} name components, it's possible that either the | 500 // {first, middle, last} name components, it's possible that either the |
497 // existing name or the imported name was misparsed. Prefer to keep the | 501 // existing name or the imported name was misparsed. Prefer to keep the |
498 // name whose {first, middle, last} components do not match those computed | 502 // name whose {first, middle, last} components do not match those computed |
499 // by the heuristic parse, as this more likely represents the correct, | 503 // by the heuristic parse, as this more likely represents the correct, |
500 // user-input parse of the name. | 504 // user-input parse of the name. |
501 NameInfo heuristically_parsed_name; | 505 NameInfo heuristically_parsed_name; |
502 heuristically_parsed_name.SetInfo(type, full_name, app_locale); | 506 heuristically_parsed_name.SetInfo(type, full_name, app_locale); |
503 if (imported_name.ParsedNamesAreEqual(heuristically_parsed_name)) | 507 if (imported_name.ParsedNamesAreEqual(heuristically_parsed_name)) |
504 return; | 508 return false; |
505 } | 509 } |
506 | 510 |
507 name_ = imported_name; | 511 name_ = imported_name; |
| 512 return true; |
508 } | 513 } |
509 | 514 |
510 void AutofillProfile::OverwriteWith(const AutofillProfile& profile, | 515 bool AutofillProfile::OverwriteWith(const AutofillProfile& profile, |
511 const std::string& app_locale) { | 516 const std::string& app_locale) { |
512 // Verified profiles should never be overwritten with unverified data. | 517 // Verified profiles should never be overwritten with unverified data. |
513 DCHECK(!IsVerified() || profile.IsVerified()); | 518 DCHECK(!IsVerified() || profile.IsVerified()); |
514 set_origin(profile.origin()); | 519 set_origin(profile.origin()); |
515 set_language_code(profile.language_code()); | 520 set_language_code(profile.language_code()); |
516 set_use_count(profile.use_count() + use_count()); | 521 set_use_count(profile.use_count() + use_count()); |
517 if (profile.use_date() > use_date()) | 522 if (profile.use_date() > use_date()) |
518 set_use_date(profile.use_date()); | 523 set_use_date(profile.use_date()); |
519 | 524 |
520 ServerFieldTypeSet field_types; | 525 ServerFieldTypeSet field_types; |
(...skipping 15 matching lines...) Expand all Loading... |
536 // previous value should not be replaced with an empty string in that case. | 541 // previous value should not be replaced with an empty string in that case. |
537 if (compare.StringsEqual( | 542 if (compare.StringsEqual( |
538 CanonicalizeProfileString( | 543 CanonicalizeProfileString( |
539 profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS)), | 544 profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS)), |
540 CanonicalizeProfileString(GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))) && | 545 CanonicalizeProfileString(GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))) && |
541 profile.GetRawInfo(ADDRESS_HOME_LINE2) == base::UTF8ToUTF16("")) { | 546 profile.GetRawInfo(ADDRESS_HOME_LINE2) == base::UTF8ToUTF16("")) { |
542 field_types.erase(ADDRESS_HOME_LINE1); | 547 field_types.erase(ADDRESS_HOME_LINE1); |
543 field_types.erase(ADDRESS_HOME_LINE2); | 548 field_types.erase(ADDRESS_HOME_LINE2); |
544 } | 549 } |
545 | 550 |
546 for (const auto& iter : field_types) { | 551 bool did_overwrite = false; |
547 FieldTypeGroup group = AutofillType(iter).group(); | 552 |
| 553 for (ServerFieldTypeSet::const_iterator iter = field_types.begin(); |
| 554 iter != field_types.end(); ++iter) { |
| 555 FieldTypeGroup group = AutofillType(*iter).group(); |
| 556 |
548 // Special case names. | 557 // Special case names. |
549 if (group == NAME) { | 558 if (group == NAME) { |
550 OverwriteName(profile.name_, app_locale); | 559 did_overwrite = OverwriteName(profile.name_, app_locale) || did_overwrite; |
551 continue; | 560 continue; |
552 } | 561 } |
553 | 562 |
554 base::string16 new_value = profile.GetRawInfo(iter); | 563 base::string16 new_value = profile.GetRawInfo(*iter); |
555 if (!compare.StringsEqual(GetRawInfo(iter), new_value)) | 564 if (!compare.StringsEqual(GetRawInfo(*iter), new_value)) { |
556 SetRawInfo(iter, new_value); | 565 SetRawInfo(*iter, new_value); |
| 566 did_overwrite = true; |
| 567 } |
557 } | 568 } |
| 569 |
| 570 return did_overwrite; |
558 } | 571 } |
559 | 572 |
560 bool AutofillProfile::SaveAdditionalInfo(const AutofillProfile& profile, | 573 bool AutofillProfile::SaveAdditionalInfo(const AutofillProfile& profile, |
561 const std::string& app_locale) { | 574 const std::string& app_locale) { |
562 ServerFieldTypeSet field_types, other_field_types; | 575 ServerFieldTypeSet field_types, other_field_types; |
563 GetNonEmptyTypes(app_locale, &field_types); | 576 GetNonEmptyTypes(app_locale, &field_types); |
564 profile.GetNonEmptyTypes(app_locale, &other_field_types); | 577 profile.GetNonEmptyTypes(app_locale, &other_field_types); |
565 // The address needs to be compared line by line to take into account the | 578 // The address needs to be compared line by line to take into account the |
566 // logic for empty fields implemented in the loop. | 579 // logic for empty fields implemented in the loop. |
567 field_types.erase(ADDRESS_HOME_STREET_ADDRESS); | 580 field_types.erase(ADDRESS_HOME_STREET_ADDRESS); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 abbreviation)) | 628 abbreviation)) |
616 continue; | 629 continue; |
617 } | 630 } |
618 if (!compare.StringsEqual(profile.GetRawInfo(field_type), | 631 if (!compare.StringsEqual(profile.GetRawInfo(field_type), |
619 GetRawInfo(field_type))) { | 632 GetRawInfo(field_type))) { |
620 return false; | 633 return false; |
621 } | 634 } |
622 } | 635 } |
623 } | 636 } |
624 | 637 |
625 if (!IsVerified() || profile.IsVerified()) | 638 if (!IsVerified() || profile.IsVerified()) { |
626 OverwriteWith(profile, app_locale); | 639 if (OverwriteWith(profile, app_locale)) { |
| 640 AutofillMetrics::LogProfileActionOnFormSubmitted( |
| 641 AutofillMetrics::EXISTING_PROFILE_UPDATED); |
| 642 } else { |
| 643 AutofillMetrics::LogProfileActionOnFormSubmitted( |
| 644 AutofillMetrics::EXISTING_PROFILE_USED); |
| 645 } |
| 646 } |
627 return true; | 647 return true; |
628 } | 648 } |
629 | 649 |
630 // static | 650 // static |
631 bool AutofillProfile::SupportsMultiValue(ServerFieldType type) { | 651 bool AutofillProfile::SupportsMultiValue(ServerFieldType type) { |
632 FieldTypeGroup group = AutofillType(type).group(); | 652 FieldTypeGroup group = AutofillType(type).group(); |
633 return group == NAME || | 653 return group == NAME || |
634 group == NAME_BILLING || | 654 group == NAME_BILLING || |
635 group == EMAIL || | 655 group == EMAIL || |
636 group == PHONE_HOME || | 656 group == PHONE_HOME || |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 << " " << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) << " " | 1024 << " " << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) << " " |
1005 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) << " " | 1025 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) << " " |
1006 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) << " " | 1026 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) << " " |
1007 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " " | 1027 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " " |
1008 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " " | 1028 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " " |
1009 << profile.language_code() << " " | 1029 << profile.language_code() << " " |
1010 << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); | 1030 << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); |
1011 } | 1031 } |
1012 | 1032 |
1013 } // namespace autofill | 1033 } // namespace autofill |
OLD | NEW |