1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/autofill/core/browser/personal_data_manager.h"
11 #include "base/i18n/timezone.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "components/autofill/core/browser/address_i18n.h"
19 #include "components/autofill/core/browser/autofill-inl.h"
20 #include "components/autofill/core/browser/autofill_country.h"
21 #include "components/autofill/core/browser/autofill_field.h"
22 #include "components/autofill/core/browser/form_structure.h"
23 #include "components/autofill/core/browser/personal_data_manager_observer.h"
24 #include "components/autofill/core/browser/phone_number.h"
25 #include "components/autofill/core/browser/phone_number_i18n.h"
26 #include "components/autofill/core/browser/validation.h"
27 #include "components/autofill/core/common/autofill_pref_names.h"
28 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
29 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
34 using ::i18n::addressinput::AddressField;
35 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine;
36 using ::i18n::addressinput::STREET_ADDRESS;
38 const base::string16::value_type kCreditCardPrefix[] = {'*', 0};
41 class FormGroupMatchesByGUIDFunctor {
43 explicit FormGroupMatchesByGUIDFunctor(const std::string& guid)
47 bool operator()(const T& form_group) {
48 return form_group.guid() == guid_;
51 bool operator()(const T* form_group) {
52 return form_group->guid() == guid_;
56 const std::string guid_;
59 template<typename T, typename C>
60 typename C::const_iterator FindElementByGUID(const C& container,
61 const std::string& guid) {
62 return std::find_if(container.begin(),
64 FormGroupMatchesByGUIDFunctor<T>(guid));
67 template<typename T, typename C>
68 bool FindByGUID(const C& container, const std::string& guid) {
69 return FindElementByGUID<T>(container, guid) != container.end();
73 class IsEmptyFunctor {
75 explicit IsEmptyFunctor(const std::string& app_locale)
76 : app_locale_(app_locale) {
79 bool operator()(const T& form_group) {
80 return form_group.IsEmpty(app_locale_);
84 const std::string app_locale_;
87 // Returns true if minimum requirements for import of a given |profile| have
88 // been met. An address submitted via a form must have at least the fields
89 // required as determined by its country code.
90 // No verification of validity of the contents is preformed. This is an
91 // existence check only.
92 bool IsMinimumAddress(const AutofillProfile& profile,
93 const std::string& app_locale) {
94 // All countries require at least one address line.
95 if (profile.GetRawInfo(ADDRESS_HOME_LINE1).empty())
98 std::string country_code =
99 base::UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
100 if (country_code.empty())
101 country_code = AutofillCountry::CountryCodeForLocale(app_locale);
103 AutofillCountry country(country_code, app_locale);
105 if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty())
108 if (country.requires_state() &&
109 profile.GetRawInfo(ADDRESS_HOME_STATE).empty())
112 if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty())
118 // Return true if the |field_type| and |value| are valid within the context
119 // of importing a form.
120 bool IsValidFieldTypeAndValue(const std::set<ServerFieldType>& types_seen,
121 ServerFieldType field_type,
122 const base::string16& value) {
123 // Abandon the import if two fields of the same type are encountered.
124 // This indicates ambiguous data or miscategorization of types.
125 // Make an exception for PHONE_HOME_NUMBER however as both prefix and
126 // suffix are stored against this type, and for EMAIL_ADDRESS because it is
127 // common to see second 'confirm email address' fields on forms.
128 if (types_seen.count(field_type) &&
129 field_type != PHONE_HOME_NUMBER &&
130 field_type != EMAIL_ADDRESS)
133 // Abandon the import if an email address value shows up in a field that is
134 // not an email address.
135 if (field_type != EMAIL_ADDRESS && IsValidEmailAddress(value))
141 // A helper function for finding the maximum value in a string->int map.
142 static bool CompareVotes(const std::pair<std::string, int>& a,
143 const std::pair<std::string, int>& b) {
144 return a.second < b.second;
149 PersonalDataManager::PersonalDataManager(const std::string& app_locale)
151 is_data_loaded_(false),
152 pending_profiles_query_(0),
153 pending_creditcards_query_(0),
154 app_locale_(app_locale),
155 metric_logger_(new AutofillMetrics),
157 is_off_the_record_(false),
158 has_logged_profile_count_(false) {}
160 void PersonalDataManager::Init(scoped_refptr<AutofillWebDataService> database,
161 PrefService* pref_service,
162 bool is_off_the_record) {
163 database_ = database;
164 SetPrefService(pref_service);
165 is_off_the_record_ = is_off_the_record;
167 if (!is_off_the_record_)
168 metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled());
170 // WebDataService may not be available in tests.
171 if (!database_.get())
177 database_->AddObserver(this);
180 PersonalDataManager::~PersonalDataManager() {
181 CancelPendingQuery(&pending_profiles_query_);
182 CancelPendingQuery(&pending_creditcards_query_);
185 database_->RemoveObserver(this);
188 void PersonalDataManager::OnWebDataServiceRequestDone(
189 WebDataServiceBase::Handle h,
190 const WDTypedResult* result) {
191 DCHECK(pending_profiles_query_ || pending_creditcards_query_);
194 // Error from the web database.
195 if (h == pending_creditcards_query_)
196 pending_creditcards_query_ = 0;
197 else if (h == pending_profiles_query_)
198 pending_profiles_query_ = 0;
202 switch (result->GetType()) {
203 case AUTOFILL_PROFILES_RESULT:
204 ReceiveLoadedProfiles(h, result);
206 case AUTOFILL_CREDITCARDS_RESULT:
207 ReceiveLoadedCreditCards(h, result);
213 // If both requests have responded, then all personal data is loaded.
214 if (pending_profiles_query_ == 0 && pending_creditcards_query_ == 0) {
215 is_data_loaded_ = true;
216 NotifyPersonalDataChanged();
220 void PersonalDataManager::AutofillMultipleChanged() {
224 void PersonalDataManager::AddObserver(PersonalDataManagerObserver* observer) {
225 observers_.AddObserver(observer);
228 void PersonalDataManager::RemoveObserver(
229 PersonalDataManagerObserver* observer) {
230 observers_.RemoveObserver(observer);
233 bool PersonalDataManager::ImportFormData(
234 const FormStructure& form,
235 scoped_ptr<CreditCard>* imported_credit_card) {
236 scoped_ptr<AutofillProfile> imported_profile(new AutofillProfile);
237 scoped_ptr<CreditCard> local_imported_credit_card(new CreditCard);
239 const std::string origin = form.source_url().spec();
240 imported_profile->set_origin(origin);
241 local_imported_credit_card->set_origin(origin);
243 // Parse the form and construct a profile based on the information that is
244 // possible to import.
245 int importable_credit_card_fields = 0;
247 // Detect and discard forms with multiple fields of the same type.
248 // TODO(isherman): Some types are overlapping but not equal, e.g. phone number
249 // parts, address parts.
250 std::set<ServerFieldType> types_seen;
252 // We only set complete phone, so aggregate phone parts in these vars and set
253 // complete at the end.
254 PhoneNumber::PhoneCombineHelper home;
256 for (size_t i = 0; i < form.field_count(); ++i) {
257 const AutofillField* field = form.field(i);
258 base::string16 value;
259 base::TrimWhitespace(field->value, base::TRIM_ALL, &value);
261 // If we don't know the type of the field, or the user hasn't entered any
262 // information into the field, then skip it.
263 if (!field->IsFieldFillable() || value.empty())
266 AutofillType field_type = field->Type();
267 ServerFieldType server_field_type = field_type.GetStorableType();
268 FieldTypeGroup group(field_type.group());
270 // There can be multiple email fields (e.g. in the case of 'confirm email'
271 // fields) but they must all contain the same value, else the profile is
273 if (server_field_type == EMAIL_ADDRESS) {
274 if (types_seen.count(server_field_type) &&
275 imported_profile->GetRawInfo(EMAIL_ADDRESS) != value) {
276 imported_profile.reset();
281 // If the |field_type| and |value| don't pass basic validity checks then
282 // abandon the import.
283 if (!IsValidFieldTypeAndValue(types_seen, server_field_type, value)) {
284 imported_profile.reset();
285 local_imported_credit_card.reset();
289 types_seen.insert(server_field_type);
291 if (group == CREDIT_CARD) {
292 if (LowerCaseEqualsASCII(field->form_control_type, "month")) {
293 DCHECK_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, server_field_type);
294 local_imported_credit_card->SetInfoForMonthInputType(value);
296 local_imported_credit_card->SetInfo(field_type, value, app_locale_);
298 ++importable_credit_card_fields;
300 // We need to store phone data in the variables, before building the whole
301 // number at the end. The rest of the fields are set "as is".
302 // If the fields are not the phone fields in question home.SetInfo() is
303 // going to return false.
304 if (!home.SetInfo(field_type, value))
305 imported_profile->SetInfo(field_type, value, app_locale_);
307 // Reject profiles with invalid country information.
308 if (server_field_type == ADDRESS_HOME_COUNTRY &&
310 imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) {
311 imported_profile.reset();
317 // Construct the phone number. Reject the profile if the number is invalid.
318 if (imported_profile.get() && !home.IsEmpty()) {
319 base::string16 constructed_number;
320 if (!home.ParseNumber(*imported_profile, app_locale_,
321 &constructed_number) ||
322 !imported_profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
325 imported_profile.reset();
329 // Reject the profile if minimum address and validation requirements are not
331 if (imported_profile.get() &&
332 !IsValidLearnableProfile(*imported_profile, app_locale_))
333 imported_profile.reset();
335 // Reject the credit card if we did not detect enough filled credit card
336 // fields or if the credit card number does not seem to be valid.
337 if (local_imported_credit_card.get() &&
338 !local_imported_credit_card->IsComplete()) {
339 local_imported_credit_card.reset();
342 // Don't import if we already have this info.
343 // Don't present an infobar if we have already saved this card number.
344 bool merged_credit_card = false;
345 if (local_imported_credit_card.get()) {
346 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
347 iter != credit_cards_.end();
349 // Make a local copy so that the data in |credit_cards_| isn't modified
350 // directly by the UpdateFromImportedCard() call.
351 CreditCard card = **iter;
352 if (card.UpdateFromImportedCard(*local_imported_credit_card.get(),
354 merged_credit_card = true;
355 UpdateCreditCard(card);
356 local_imported_credit_card.reset();
362 if (imported_profile.get()) {
363 // We always save imported profiles.
364 SaveImportedProfile(*imported_profile);
366 *imported_credit_card = local_imported_credit_card.Pass();
368 if (imported_profile.get() || *imported_credit_card || merged_credit_card)
371 FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
372 OnInsufficientFormData());
376 void PersonalDataManager::AddProfile(const AutofillProfile& profile) {
377 if (is_off_the_record_)
380 if (profile.IsEmpty(app_locale_))
383 // Don't add an existing profile.
384 if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()))
387 if (!database_.get())
390 // Don't add a duplicate.
391 if (FindByContents(web_profiles_, profile))
394 // Add the new profile to the web database.
395 database_->AddAutofillProfile(profile);
397 // Refresh our local cache and send notifications to observers.
401 void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
402 if (is_off_the_record_)
405 AutofillProfile* existing_profile = GetProfileByGUID(profile.guid());
406 if (!existing_profile)
409 // Don't overwrite the origin for a profile that is already stored.
410 if (existing_profile->EqualsSansOrigin(profile))
413 if (profile.IsEmpty(app_locale_)) {
414 RemoveByGUID(profile.guid());
418 if (!database_.get())
422 database_->UpdateAutofillProfile(profile);
424 // Refresh our local cache and send notifications to observers.
428 AutofillProfile* PersonalDataManager::GetProfileByGUID(
429 const std::string& guid) {
430 const std::vector<AutofillProfile*>& profiles = GetProfiles();
431 std::vector<AutofillProfile*>::const_iterator iter =
432 FindElementByGUID<AutofillProfile>(profiles, guid);
433 return (iter != profiles.end()) ? *iter : NULL;
436 void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) {
437 if (is_off_the_record_)
440 if (credit_card.IsEmpty(app_locale_))
443 if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid()))
446 if (!database_.get())
449 // Don't add a duplicate.
450 if (FindByContents(credit_cards_, credit_card))
453 // Add the new credit card to the web database.
454 database_->AddCreditCard(credit_card);
456 // Refresh our local cache and send notifications to observers.
460 void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
461 if (is_off_the_record_)
464 CreditCard* existing_credit_card = GetCreditCardByGUID(credit_card.guid());
465 if (!existing_credit_card)
468 // Don't overwrite the origin for a credit card that is already stored.
469 if (existing_credit_card->Compare(credit_card) == 0)
472 if (credit_card.IsEmpty(app_locale_)) {
473 RemoveByGUID(credit_card.guid());
477 if (!database_.get())
481 database_->UpdateCreditCard(credit_card);
483 // Refresh our local cache and send notifications to observers.
487 void PersonalDataManager::RemoveByGUID(const std::string& guid) {
488 if (is_off_the_record_)
491 bool is_credit_card = FindByGUID<CreditCard>(credit_cards_, guid);
492 bool is_profile = !is_credit_card &&
493 FindByGUID<AutofillProfile>(web_profiles_, guid);
494 if (!is_credit_card && !is_profile)
497 if (!database_.get())
501 database_->RemoveCreditCard(guid);
503 database_->RemoveAutofillProfile(guid);
505 // Refresh our local cache and send notifications to observers.
509 CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) {
510 const std::vector<CreditCard*>& credit_cards = GetCreditCards();
511 std::vector<CreditCard*>::const_iterator iter =
512 FindElementByGUID<CreditCard>(credit_cards, guid);
513 return (iter != credit_cards.end()) ? *iter : NULL;
516 void PersonalDataManager::GetNonEmptyTypes(
517 ServerFieldTypeSet* non_empty_types) {
518 const std::vector<AutofillProfile*>& profiles = GetProfiles();
519 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
520 iter != profiles.end(); ++iter) {
521 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
524 for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin();
525 iter != credit_cards_.end(); ++iter) {
526 (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
530 bool PersonalDataManager::IsDataLoaded() const {
531 return is_data_loaded_;
534 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const {
535 return GetProfiles(false);
538 const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const {
539 return web_profiles_.get();
542 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
543 return credit_cards_.get();
546 void PersonalDataManager::Refresh() {
551 void PersonalDataManager::GetProfileSuggestions(
552 const AutofillType& type,
553 const base::string16& field_contents,
554 bool field_is_autofilled,
555 const std::vector<ServerFieldType>& other_field_types,
556 const base::Callback<bool(const AutofillProfile&)>& filter,
557 std::vector<base::string16>* values,
558 std::vector<base::string16>* labels,
559 std::vector<base::string16>* icons,
560 std::vector<GUIDPair>* guid_pairs) {
566 const std::vector<AutofillProfile*>& profiles = GetProfiles(true);
567 std::vector<AutofillProfile*> matched_profiles;
568 for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
569 iter != profiles.end(); ++iter) {
570 AutofillProfile* profile = *iter;
572 // The value of the stored data for this field type in the |profile|.
573 std::vector<base::string16> multi_values;
574 AddressField address_field;
575 if (i18n::FieldForType(type.GetStorableType(), &address_field) &&
576 address_field == STREET_ADDRESS) {
577 std::string street_address_line;
578 GetStreetAddressLinesAsSingleLine(
579 *i18n::CreateAddressDataFromAutofillProfile(*profile, app_locale_),
580 &street_address_line);
581 multi_values.push_back(base::UTF8ToUTF16(street_address_line));
583 profile->GetMultiInfo(type, app_locale_, &multi_values);
586 for (size_t i = 0; i < multi_values.size(); ++i) {
587 // Newlines can be found only in a street address, which was collapsed
588 // into a single line above.
589 DCHECK(multi_values[i].find('\n') == std::string::npos);
591 if (!field_is_autofilled) {
592 // Suggest data that starts with what the user has typed.
593 if (!multi_values[i].empty() &&
594 StartsWith(multi_values[i], field_contents, false) &&
595 (filter.is_null() || filter.Run(*profile))) {
596 matched_profiles.push_back(profile);
597 values->push_back(multi_values[i]);
598 guid_pairs->push_back(GUIDPair(profile->guid(), i));
601 if (multi_values[i].empty())
604 base::string16 profile_value_lower_case(
605 base::StringToLowerASCII(multi_values[i]));
606 base::string16 field_value_lower_case(
607 base::StringToLowerASCII(field_contents));
608 // Phone numbers could be split in US forms, so field value could be
609 // either prefix or suffix of the phone.
610 bool matched_phones = false;
611 if (type.GetStorableType() == PHONE_HOME_NUMBER &&
612 !field_value_lower_case.empty() &&
613 profile_value_lower_case.find(field_value_lower_case) !=
614 base::string16::npos) {
615 matched_phones = true;
618 // Suggest variants of the profile that's already been filled in.
619 if (matched_phones ||
620 profile_value_lower_case == field_value_lower_case) {
621 for (size_t j = 0; j < multi_values.size(); ++j) {
622 if (!multi_values[j].empty()) {
623 values->push_back(multi_values[j]);
624 guid_pairs->push_back(GUIDPair(profile->guid(), j));
628 // We've added all the values for this profile so move on to the
636 if (!field_is_autofilled) {
637 AutofillProfile::CreateInferredLabels(
638 matched_profiles, &other_field_types,
639 type.GetStorableType(), 1, app_locale_, labels);
641 // No sub-labels for previously filled fields.
642 labels->resize(values->size());
645 // No icons for profile suggestions.
646 icons->resize(values->size());
649 void PersonalDataManager::GetCreditCardSuggestions(
650 const AutofillType& type,
651 const base::string16& field_contents,
652 std::vector<base::string16>* values,
653 std::vector<base::string16>* labels,
654 std::vector<base::string16>* icons,
655 std::vector<GUIDPair>* guid_pairs) {
661 const std::vector<CreditCard*>& credit_cards = GetCreditCards();
662 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
663 iter != credit_cards.end(); ++iter) {
664 CreditCard* credit_card = *iter;
666 // The value of the stored data for this field type in the |credit_card|.
667 base::string16 creditcard_field_value =
668 credit_card->GetInfo(type, app_locale_);
669 if (!creditcard_field_value.empty() &&
670 StartsWith(creditcard_field_value, field_contents, false)) {
671 if (type.GetStorableType() == CREDIT_CARD_NUMBER)
672 creditcard_field_value = credit_card->ObfuscatedNumber();
674 // If the value is the card number, the label is the expiration date.
675 // Otherwise the label is the card number, or if that is empty the
676 // cardholder name. The label should never repeat the value.
677 base::string16 label;
678 if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
679 label = credit_card->GetInfo(
680 AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_);
681 } else if (credit_card->number().empty()) {
682 if (type.GetStorableType() != CREDIT_CARD_NAME) {
684 credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_);
687 label = kCreditCardPrefix;
688 label.append(credit_card->LastFourDigits());
691 values->push_back(creditcard_field_value);
692 labels->push_back(label);
693 icons->push_back(base::UTF8ToUTF16(credit_card->type()));
694 guid_pairs->push_back(GUIDPair(credit_card->guid(), 0));
699 bool PersonalDataManager::IsAutofillEnabled() const {
700 DCHECK(pref_service_);
701 return pref_service_->GetBoolean(prefs::kAutofillEnabled);
704 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const {
705 return base::CountryCodeForCurrentTimezone();
708 void PersonalDataManager::SetPrefService(PrefService* pref_service) {
709 enabled_pref_.reset(new BooleanPrefMember);
710 pref_service_ = pref_service;
711 // |pref_service_| can be NULL in tests.
713 enabled_pref_->Init(prefs::kAutofillEnabled, pref_service_,
714 base::Bind(&PersonalDataManager::EnabledPrefChanged,
715 base::Unretained(this)));
720 bool PersonalDataManager::IsValidLearnableProfile(
721 const AutofillProfile& profile,
722 const std::string& app_locale) {
723 if (!IsMinimumAddress(profile, app_locale))
726 base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS);
727 if (!email.empty() && !IsValidEmailAddress(email))
730 // Reject profiles with invalid US state information.
731 if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE))
734 // Reject profiles with invalid US zip information.
735 if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP))
742 std::string PersonalDataManager::MergeProfile(
743 const AutofillProfile& new_profile,
744 const std::vector<AutofillProfile*>& existing_profiles,
745 const std::string& app_locale,
746 std::vector<AutofillProfile>* merged_profiles) {
747 merged_profiles->clear();
749 // Set to true if |existing_profiles| already contains an equivalent profile.
750 bool matching_profile_found = false;
751 std::string guid = new_profile.guid();
753 // If we have already saved this address, merge in any missing values.
754 // Only merge with the first match.
755 for (std::vector<AutofillProfile*>::const_iterator iter =
756 existing_profiles.begin();
757 iter != existing_profiles.end(); ++iter) {
758 AutofillProfile* existing_profile = *iter;
759 if (!matching_profile_found &&
760 !new_profile.PrimaryValue().empty() &&
761 base::StringToLowerASCII(existing_profile->PrimaryValue()) ==
762 base::StringToLowerASCII(new_profile.PrimaryValue())) {
763 // Unverified profiles should always be updated with the newer data,
764 // whereas verified profiles should only ever be overwritten by verified
765 // data. If an automatically aggregated profile would overwrite a
766 // verified profile, just drop it.
767 matching_profile_found = true;
768 guid = existing_profile->guid();
769 if (!existing_profile->IsVerified() || new_profile.IsVerified())
770 existing_profile->OverwriteWithOrAddTo(new_profile, app_locale);
772 merged_profiles->push_back(*existing_profile);
775 // If the new profile was not merged with an existing one, add it to the list.
776 if (!matching_profile_found)
777 merged_profiles->push_back(new_profile);
782 bool PersonalDataManager::IsCountryOfInterest(const std::string& country_code)
784 DCHECK_EQ(2U, country_code.size());
786 const std::vector<AutofillProfile*>& profiles = web_profiles();
787 std::list<std::string> country_codes;
788 for (size_t i = 0; i < profiles.size(); ++i) {
789 country_codes.push_back(base::StringToLowerASCII(base::UTF16ToASCII(
790 profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY))));
793 std::string timezone_country = CountryCodeForCurrentTimezone();
794 if (!timezone_country.empty())
795 country_codes.push_back(base::StringToLowerASCII(timezone_country));
797 // Only take the locale into consideration if all else fails.
798 if (country_codes.empty()) {
799 country_codes.push_back(base::StringToLowerASCII(
800 AutofillCountry::CountryCodeForLocale(app_locale())));
803 return std::find(country_codes.begin(), country_codes.end(),
804 base::StringToLowerASCII(country_code)) !=
808 const std::string& PersonalDataManager::GetDefaultCountryCodeForNewAddress()
810 if (default_country_code_.empty())
811 default_country_code_ = MostCommonCountryCodeFromProfiles();
813 // Failing that, guess based on system timezone.
814 if (default_country_code_.empty())
815 default_country_code_ = CountryCodeForCurrentTimezone();
817 // Failing that, guess based on locale.
818 if (default_country_code_.empty())
819 default_country_code_ = AutofillCountry::CountryCodeForLocale(app_locale());
821 return default_country_code_;
824 void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
825 if (is_off_the_record_)
828 // Remove empty profiles from input.
829 profiles->erase(std::remove_if(profiles->begin(), profiles->end(),
830 IsEmptyFunctor<AutofillProfile>(app_locale_)),
833 if (!database_.get())
836 // Any profiles that are not in the new profile list should be removed from
838 for (std::vector<AutofillProfile*>::const_iterator iter =
839 web_profiles_.begin();
840 iter != web_profiles_.end(); ++iter) {
841 if (!FindByGUID<AutofillProfile>(*profiles, (*iter)->guid()))
842 database_->RemoveAutofillProfile((*iter)->guid());
845 // Update the web database with the existing profiles.
846 for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
847 iter != profiles->end(); ++iter) {
848 if (FindByGUID<AutofillProfile>(web_profiles_, iter->guid()))
849 database_->UpdateAutofillProfile(*iter);
852 // Add the new profiles to the web database. Don't add a duplicate.
853 for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
854 iter != profiles->end(); ++iter) {
855 if (!FindByGUID<AutofillProfile>(web_profiles_, iter->guid()) &&
856 !FindByContents(web_profiles_, *iter))
857 database_->AddAutofillProfile(*iter);
860 // Copy in the new profiles.
861 web_profiles_.clear();
862 for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
863 iter != profiles->end(); ++iter) {
864 web_profiles_.push_back(new AutofillProfile(*iter));
867 // Refresh our local cache and send notifications to observers.
871 void PersonalDataManager::SetCreditCards(
872 std::vector<CreditCard>* credit_cards) {
873 if (is_off_the_record_)
876 // Remove empty credit cards from input.
877 credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(),
878 IsEmptyFunctor<CreditCard>(app_locale_)),
879 credit_cards->end());
881 if (!database_.get())
884 // Any credit cards that are not in the new credit card list should be
886 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
887 iter != credit_cards_.end(); ++iter) {
888 if (!FindByGUID<CreditCard>(*credit_cards, (*iter)->guid()))
889 database_->RemoveCreditCard((*iter)->guid());
892 // Update the web database with the existing credit cards.
893 for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
894 iter != credit_cards->end(); ++iter) {
895 if (FindByGUID<CreditCard>(credit_cards_, iter->guid()))
896 database_->UpdateCreditCard(*iter);
899 // Add the new credit cards to the web database. Don't add a duplicate.
900 for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
901 iter != credit_cards->end(); ++iter) {
902 if (!FindByGUID<CreditCard>(credit_cards_, iter->guid()) &&
903 !FindByContents(credit_cards_, *iter))
904 database_->AddCreditCard(*iter);
907 // Copy in the new credit cards.
908 credit_cards_.clear();
909 for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
910 iter != credit_cards->end(); ++iter) {
911 credit_cards_.push_back(new CreditCard(*iter));
914 // Refresh our local cache and send notifications to observers.
918 void PersonalDataManager::LoadProfiles() {
919 if (!database_.get()) {
924 CancelPendingQuery(&pending_profiles_query_);
926 pending_profiles_query_ = database_->GetAutofillProfiles(this);
929 // Win, Linux, Android and iOS implementations do nothing. Mac implementation
930 // fills in the contents of |auxiliary_profiles_|.
931 #if defined(OS_IOS) || !defined(OS_MACOSX)
932 void PersonalDataManager::LoadAuxiliaryProfiles(bool record_metrics) const {
936 void PersonalDataManager::LoadCreditCards() {
937 if (!database_.get()) {
942 CancelPendingQuery(&pending_creditcards_query_);
944 pending_creditcards_query_ = database_->GetCreditCards(this);
947 void PersonalDataManager::ReceiveLoadedProfiles(WebDataServiceBase::Handle h,
948 const WDTypedResult* result) {
949 DCHECK_EQ(pending_profiles_query_, h);
951 pending_profiles_query_ = 0;
952 web_profiles_.clear();
954 const WDResult<std::vector<AutofillProfile*> >* r =
955 static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result);
957 std::vector<AutofillProfile*> profiles = r->GetValue();
958 for (std::vector<AutofillProfile*>::iterator iter = profiles.begin();
959 iter != profiles.end(); ++iter) {
960 web_profiles_.push_back(*iter);
966 void PersonalDataManager::ReceiveLoadedCreditCards(
967 WebDataServiceBase::Handle h, const WDTypedResult* result) {
968 DCHECK_EQ(pending_creditcards_query_, h);
970 pending_creditcards_query_ = 0;
971 credit_cards_.clear();
973 const WDResult<std::vector<CreditCard*> >* r =
974 static_cast<const WDResult<std::vector<CreditCard*> >*>(result);
976 std::vector<CreditCard*> credit_cards = r->GetValue();
977 for (std::vector<CreditCard*>::iterator iter = credit_cards.begin();
978 iter != credit_cards.end(); ++iter) {
979 credit_cards_.push_back(*iter);
983 void PersonalDataManager::CancelPendingQuery(
984 WebDataServiceBase::Handle* handle) {
986 if (!database_.get()) {
990 database_->CancelRequest(*handle);
995 std::string PersonalDataManager::SaveImportedProfile(
996 const AutofillProfile& imported_profile) {
997 if (is_off_the_record_)
998 return std::string();
1000 // Don't save a web profile if the data in the profile is a subset of an
1001 // auxiliary profile.
1002 for (std::vector<AutofillProfile*>::const_iterator iter =
1003 auxiliary_profiles_.begin();
1004 iter != auxiliary_profiles_.end(); ++iter) {
1005 if (imported_profile.IsSubsetOf(**iter, app_locale_))
1006 return (*iter)->guid();
1009 std::vector<AutofillProfile> profiles;
1011 MergeProfile(imported_profile, web_profiles_.get(), app_locale_,
1013 SetProfiles(&profiles);
1017 void PersonalDataManager::NotifyPersonalDataChanged() {
1018 FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
1019 OnPersonalDataChanged());
1022 std::string PersonalDataManager::SaveImportedCreditCard(
1023 const CreditCard& imported_card) {
1024 DCHECK(!imported_card.number().empty());
1025 if (is_off_the_record_)
1026 return std::string();
1028 // Set to true if |imported_card| is merged into the credit card list.
1029 bool merged = false;
1031 std::string guid = imported_card.guid();
1032 std::vector<CreditCard> credit_cards;
1033 for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
1034 iter != credit_cards_.end();
1036 CreditCard* card = *iter;
1037 // If |imported_card| has not yet been merged, check whether it should be
1038 // with the current |card|.
1039 if (!merged && card->UpdateFromImportedCard(imported_card, app_locale_)) {
1040 guid = card->guid();
1044 credit_cards.push_back(*card);
1048 credit_cards.push_back(imported_card);
1050 SetCreditCards(&credit_cards);
1054 void PersonalDataManager::LogProfileCount() const {
1055 if (!has_logged_profile_count_) {
1056 metric_logger_->LogStoredProfileCount(web_profiles_.size());
1057 has_logged_profile_count_ = true;
1061 std::string PersonalDataManager::MostCommonCountryCodeFromProfiles() const {
1062 if (!IsAutofillEnabled())
1063 return std::string();
1065 // Count up country codes from existing profiles.
1066 std::map<std::string, int> votes;
1067 // TODO(estade): can we make this GetProfiles() instead? It seems to cause
1068 // errors in tests on mac trybots. See http://crbug.com/57221
1069 const std::vector<AutofillProfile*>& profiles = web_profiles();
1070 std::vector<std::string> country_codes;
1071 AutofillCountry::GetAvailableCountries(&country_codes);
1072 for (size_t i = 0; i < profiles.size(); ++i) {
1073 std::string country_code = StringToUpperASCII(base::UTF16ToASCII(
1074 profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY)));
1076 if (std::find(country_codes.begin(), country_codes.end(), country_code) !=
1077 country_codes.end()) {
1078 // Verified profiles count 100x more than unverified ones.
1079 votes[country_code] += profiles[i]->IsVerified() ? 100 : 1;
1083 // Take the most common country code.
1084 if (!votes.empty()) {
1085 std::map<std::string, int>::iterator iter =
1086 std::max_element(votes.begin(), votes.end(), CompareVotes);
1090 return std::string();
1093 void PersonalDataManager::EnabledPrefChanged() {
1094 default_country_code_.clear();
1095 NotifyPersonalDataChanged();
1098 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles(
1099 bool record_metrics) const {
1100 #if defined(OS_MACOSX) && !defined(OS_IOS)
1101 if (!pref_service_->GetBoolean(prefs::kAutofillUseMacAddressBook))
1102 return web_profiles();
1104 if (!pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled))
1105 return web_profiles();
1106 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
1110 // Populates |auxiliary_profiles_|.
1111 LoadAuxiliaryProfiles(record_metrics);
1113 profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end());
1115 profiles_.end(), auxiliary_profiles_.begin(), auxiliary_profiles_.end());
1119 } // namespace autofill