Index: components/autofill/browser/personal_data_manager.cc |
diff --git a/components/autofill/browser/personal_data_manager.cc b/components/autofill/browser/personal_data_manager.cc |
deleted file mode 100644 |
index 021944ba4379ff49f18dfdd32f12a0370c07463c..0000000000000000000000000000000000000000 |
--- a/components/autofill/browser/personal_data_manager.cc |
+++ /dev/null |
@@ -1,1031 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "components/autofill/browser/personal_data_manager.h" |
- |
-#include <algorithm> |
-#include <functional> |
-#include <iterator> |
- |
-#include "base/logging.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/prefs/pref_service.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "components/autofill/browser/autofill-inl.h" |
-#include "components/autofill/browser/autofill_country.h" |
-#include "components/autofill/browser/autofill_field.h" |
-#include "components/autofill/browser/autofill_metrics.h" |
-#include "components/autofill/browser/form_structure.h" |
-#include "components/autofill/browser/personal_data_manager_observer.h" |
-#include "components/autofill/browser/phone_number.h" |
-#include "components/autofill/browser/phone_number_i18n.h" |
-#include "components/autofill/browser/validation.h" |
-#include "components/autofill/browser/webdata/autofill_webdata_service.h" |
-#include "components/autofill/core/common/autofill_pref_names.h" |
-#include "components/user_prefs/user_prefs.h" |
-#include "content/public/browser/browser_context.h" |
- |
-using content::BrowserContext; |
- |
-namespace autofill { |
-namespace { |
- |
-const base::string16::value_type kCreditCardPrefix[] = {'*', 0}; |
- |
-template<typename T> |
-class FormGroupMatchesByGUIDFunctor { |
- public: |
- explicit FormGroupMatchesByGUIDFunctor(const std::string& guid) |
- : guid_(guid) { |
- } |
- |
- bool operator()(const T& form_group) { |
- return form_group.guid() == guid_; |
- } |
- |
- bool operator()(const T* form_group) { |
- return form_group->guid() == guid_; |
- } |
- |
- private: |
- std::string guid_; |
-}; |
- |
-template<typename T, typename C> |
-bool FindByGUID(const C& container, const std::string& guid) { |
- return std::find_if( |
- container.begin(), |
- container.end(), |
- FormGroupMatchesByGUIDFunctor<T>(guid)) != container.end(); |
-} |
- |
-template<typename T> |
-class DereferenceFunctor { |
- public: |
- template<typename T_Iterator> |
- const T& operator()(const T_Iterator& iterator) { |
- return *iterator; |
- } |
-}; |
- |
-template<typename T> |
-T* address_of(T& v) { |
- return &v; |
-} |
- |
-// Returns true if minimum requirements for import of a given |profile| have |
-// been met. An address submitted via a form must have at least the fields |
-// required as determined by its country code. |
-// No verification of validity of the contents is preformed. This is an |
-// existence check only. |
-bool IsMinimumAddress(const AutofillProfile& profile, |
- const std::string& app_locale) { |
- // All countries require at least one address line. |
- if (profile.GetRawInfo(ADDRESS_HOME_LINE1).empty()) |
- return false; |
- std::string country_code = |
- UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)); |
- |
- if (country_code.empty()) |
- country_code = AutofillCountry::CountryCodeForLocale(app_locale); |
- |
- AutofillCountry country(country_code, app_locale); |
- |
- if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty()) |
- return false; |
- |
- if (country.requires_state() && |
- profile.GetRawInfo(ADDRESS_HOME_STATE).empty()) |
- return false; |
- |
- if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty()) |
- return false; |
- |
- return true; |
-} |
- |
-// Return true if the |field_type| and |value| are valid within the context |
-// of importing a form. |
-bool IsValidFieldTypeAndValue(const std::set<AutofillFieldType>& types_seen, |
- AutofillFieldType field_type, |
- const base::string16& value) { |
- // Abandon the import if two fields of the same type are encountered. |
- // This indicates ambiguous data or miscategorization of types. |
- // Make an exception for PHONE_HOME_NUMBER however as both prefix and |
- // suffix are stored against this type, and for EMAIL_ADDRESS because it is |
- // common to see second 'confirm email address' fields on forms. |
- if (types_seen.count(field_type) && field_type != PHONE_HOME_NUMBER && |
- field_type != EMAIL_ADDRESS) |
- return false; |
- |
- // Abandon the import if an email address value shows up in a field that is |
- // not an email address. |
- if (field_type != EMAIL_ADDRESS && autofill::IsValidEmailAddress(value)) |
- return false; |
- |
- return true; |
-} |
- |
-} // namespace |
- |
-PersonalDataManager::PersonalDataManager(const std::string& app_locale) |
- : browser_context_(NULL), |
- is_data_loaded_(false), |
- pending_profiles_query_(0), |
- pending_creditcards_query_(0), |
- app_locale_(app_locale), |
- metric_logger_(new AutofillMetrics), |
- has_logged_profile_count_(false) {} |
- |
-void PersonalDataManager::Init(BrowserContext* browser_context) { |
- browser_context_ = browser_context; |
- |
- if (!browser_context_->IsOffTheRecord()) |
- metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled()); |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- |
- // WebDataService may not be available in tests. |
- if (!autofill_data.get()) |
- return; |
- |
- LoadProfiles(); |
- LoadCreditCards(); |
- |
- autofill_data->AddObserver(this); |
-} |
- |
-PersonalDataManager::~PersonalDataManager() { |
- CancelPendingQuery(&pending_profiles_query_); |
- CancelPendingQuery(&pending_creditcards_query_); |
- |
- if (!browser_context_) |
- return; |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (autofill_data.get()) |
- autofill_data->RemoveObserver(this); |
-} |
- |
-void PersonalDataManager::OnWebDataServiceRequestDone( |
- WebDataServiceBase::Handle h, |
- const WDTypedResult* result) { |
- DCHECK(pending_profiles_query_ || pending_creditcards_query_); |
- |
- if (!result) { |
- // Error from the web database. |
- if (h == pending_creditcards_query_) |
- pending_creditcards_query_ = 0; |
- else if (h == pending_profiles_query_) |
- pending_profiles_query_ = 0; |
- return; |
- } |
- |
- DCHECK(result->GetType() == AUTOFILL_PROFILES_RESULT || |
- result->GetType() == AUTOFILL_CREDITCARDS_RESULT); |
- |
- switch (result->GetType()) { |
- case AUTOFILL_PROFILES_RESULT: |
- ReceiveLoadedProfiles(h, result); |
- break; |
- case AUTOFILL_CREDITCARDS_RESULT: |
- ReceiveLoadedCreditCards(h, result); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- |
- // If both requests have responded, then all personal data is loaded. |
- if (pending_profiles_query_ == 0 && pending_creditcards_query_ == 0) { |
- is_data_loaded_ = true; |
- std::vector<AutofillProfile*> profile_pointers(web_profiles_.size()); |
- std::copy(web_profiles_.begin(), web_profiles_.end(), |
- profile_pointers.begin()); |
- AutofillProfile::AdjustInferredLabels(&profile_pointers); |
- FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_, |
- OnPersonalDataChanged()); |
- } |
-} |
- |
-void PersonalDataManager::AutofillMultipleChanged() { |
- Refresh(); |
-} |
- |
-void PersonalDataManager::AddObserver(PersonalDataManagerObserver* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void PersonalDataManager::RemoveObserver( |
- PersonalDataManagerObserver* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
-bool PersonalDataManager::ImportFormData( |
- const FormStructure& form, |
- const CreditCard** imported_credit_card) { |
- scoped_ptr<AutofillProfile> imported_profile(new AutofillProfile); |
- scoped_ptr<CreditCard> local_imported_credit_card(new CreditCard); |
- |
- const std::string origin = form.source_url().spec(); |
- imported_profile->set_origin(origin); |
- local_imported_credit_card->set_origin(origin); |
- |
- // Parse the form and construct a profile based on the information that is |
- // possible to import. |
- int importable_credit_card_fields = 0; |
- |
- // Detect and discard forms with multiple fields of the same type. |
- std::set<AutofillFieldType> types_seen; |
- |
- // We only set complete phone, so aggregate phone parts in these vars and set |
- // complete at the end. |
- PhoneNumber::PhoneCombineHelper home; |
- |
- for (size_t i = 0; i < form.field_count(); ++i) { |
- const AutofillField* field = form.field(i); |
- base::string16 value = CollapseWhitespace(field->value, false); |
- |
- // If we don't know the type of the field, or the user hasn't entered any |
- // information into the field, then skip it. |
- if (!field->IsFieldFillable() || value.empty()) |
- continue; |
- |
- AutofillFieldType field_type = field->type(); |
- FieldTypeGroup group(AutofillType(field_type).group()); |
- |
- // There can be multiple email fields (e.g. in the case of 'confirm email' |
- // fields) but they must all contain the same value, else the profile is |
- // invalid. |
- if (field_type == EMAIL_ADDRESS) { |
- if (types_seen.count(field_type) && |
- imported_profile->GetRawInfo(field_type) != value) { |
- imported_profile.reset(); |
- break; |
- } |
- } |
- |
- // If the |field_type| and |value| don't pass basic validity checks then |
- // abandon the import. |
- if (!IsValidFieldTypeAndValue(types_seen, field_type, value)) { |
- imported_profile.reset(); |
- local_imported_credit_card.reset(); |
- break; |
- } |
- |
- types_seen.insert(field_type); |
- |
- if (group == AutofillType::CREDIT_CARD) { |
- if (LowerCaseEqualsASCII(field->form_control_type, "month")) { |
- DCHECK_EQ(CREDIT_CARD_EXP_MONTH, field_type); |
- local_imported_credit_card->SetInfoForMonthInputType(value); |
- } else { |
- local_imported_credit_card->SetInfo(field_type, value, app_locale_); |
- } |
- ++importable_credit_card_fields; |
- } else { |
- // We need to store phone data in the variables, before building the whole |
- // number at the end. The rest of the fields are set "as is". |
- // If the fields are not the phone fields in question home.SetInfo() is |
- // going to return false. |
- if (!home.SetInfo(field_type, value)) |
- imported_profile->SetInfo(field_type, value, app_locale_); |
- |
- // Reject profiles with invalid country information. |
- if (field_type == ADDRESS_HOME_COUNTRY && |
- !value.empty() && |
- imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) { |
- imported_profile.reset(); |
- break; |
- } |
- } |
- } |
- |
- // Construct the phone number. Reject the profile if the number is invalid. |
- if (imported_profile.get() && !home.IsEmpty()) { |
- base::string16 constructed_number; |
- if (!home.ParseNumber(*imported_profile, app_locale_, |
- &constructed_number) || |
- !imported_profile->SetInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number, |
- app_locale_)) { |
- imported_profile.reset(); |
- } |
- } |
- |
- // Reject the profile if minimum address and validation requirements are not |
- // met. |
- if (imported_profile.get() && |
- !IsValidLearnableProfile(*imported_profile, app_locale_)) |
- imported_profile.reset(); |
- |
- // Reject the credit card if we did not detect enough filled credit card |
- // fields or if the credit card number does not seem to be valid. |
- if (local_imported_credit_card.get() && |
- !local_imported_credit_card->IsComplete()) { |
- local_imported_credit_card.reset(); |
- } |
- |
- // Don't import if we already have this info. |
- // Don't present an infobar if we have already saved this card number. |
- bool merged_credit_card = false; |
- if (local_imported_credit_card.get()) { |
- for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin(); |
- iter != credit_cards_.end(); |
- ++iter) { |
- // Make a local copy so that the data in |credit_cards_| isn't modified |
- // directly by the UpdateFromImportedCard() call. |
- CreditCard card = **iter; |
- if (card.UpdateFromImportedCard(*local_imported_credit_card.get(), |
- app_locale_)) { |
- merged_credit_card = true; |
- UpdateCreditCard(card); |
- local_imported_credit_card.reset(); |
- break; |
- } |
- } |
- } |
- |
- if (imported_profile.get()) { |
- // We always save imported profiles. |
- SaveImportedProfile(*imported_profile); |
- } |
- *imported_credit_card = local_imported_credit_card.release(); |
- |
- if (imported_profile.get() || *imported_credit_card || merged_credit_card) { |
- return true; |
- } else { |
- FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_, |
- OnInsufficientFormData()); |
- return false; |
- } |
-} |
- |
-void PersonalDataManager::AddProfile(const AutofillProfile& profile) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- if (profile.IsEmpty(app_locale_)) |
- return; |
- |
- // Don't add an existing profile. |
- if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid())) |
- return; |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- // Don't add a duplicate. |
- if (FindByContents(web_profiles_, profile)) |
- return; |
- |
- // Add the new profile to the web database. |
- autofill_data->AddAutofillProfile(profile); |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- AutofillProfile* existing_profile = GetProfileByGUID(profile.guid()); |
- if (!existing_profile) |
- return; |
- |
- // Don't overwrite the origin for a profile that is already stored. |
- if (existing_profile->Compare(profile) == 0) |
- return; |
- |
- if (profile.IsEmpty(app_locale_)) { |
- RemoveByGUID(profile.guid()); |
- return; |
- } |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- // Make the update. |
- autofill_data->UpdateAutofillProfile(profile); |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-AutofillProfile* PersonalDataManager::GetProfileByGUID( |
- const std::string& guid) { |
- const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
- for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); |
- iter != profiles.end(); ++iter) { |
- if ((*iter)->guid() == guid) |
- return *iter; |
- } |
- return NULL; |
-} |
- |
-void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- if (credit_card.IsEmpty(app_locale_)) |
- return; |
- |
- if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid())) |
- return; |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- // Don't add a duplicate. |
- if (FindByContents(credit_cards_, credit_card)) |
- return; |
- |
- // Add the new credit card to the web database. |
- autofill_data->AddCreditCard(credit_card); |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- CreditCard* existing_credit_card = GetCreditCardByGUID(credit_card.guid()); |
- if (!existing_credit_card) |
- return; |
- |
- // Don't overwrite the origin for a credit card that is already stored. |
- if (existing_credit_card->Compare(credit_card) == 0) |
- return; |
- |
- if (credit_card.IsEmpty(app_locale_)) { |
- RemoveByGUID(credit_card.guid()); |
- return; |
- } |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- // Make the update. |
- autofill_data->UpdateCreditCard(credit_card); |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-void PersonalDataManager::RemoveByGUID(const std::string& guid) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- bool is_credit_card = FindByGUID<CreditCard>(credit_cards_, guid); |
- bool is_profile = !is_credit_card && |
- FindByGUID<AutofillProfile>(web_profiles_, guid); |
- if (!is_credit_card && !is_profile) |
- return; |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- if (is_credit_card) |
- autofill_data->RemoveCreditCard(guid); |
- else |
- autofill_data->RemoveAutofillProfile(guid); |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) { |
- const std::vector<CreditCard*>& credit_cards = GetCreditCards(); |
- for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); |
- iter != credit_cards.end(); ++iter) { |
- if ((*iter)->guid() == guid) |
- return *iter; |
- } |
- return NULL; |
-} |
- |
-void PersonalDataManager::GetNonEmptyTypes( |
- FieldTypeSet* non_empty_types) { |
- const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
- for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); |
- iter != profiles.end(); ++iter) { |
- (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); |
- } |
- |
- for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin(); |
- iter != credit_cards_.end(); ++iter) { |
- (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types); |
- } |
-} |
- |
-bool PersonalDataManager::IsDataLoaded() const { |
- return is_data_loaded_; |
-} |
- |
-const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() { |
- if (!user_prefs::UserPrefs::Get(browser_context_)->GetBoolean( |
- prefs::kAutofillAuxiliaryProfilesEnabled)) { |
- return web_profiles(); |
- } |
- |
- profiles_.clear(); |
- |
- // Populates |auxiliary_profiles_|. |
- LoadAuxiliaryProfiles(); |
- |
- profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end()); |
- profiles_.insert(profiles_.end(), |
- auxiliary_profiles_.begin(), auxiliary_profiles_.end()); |
- return profiles_; |
-} |
- |
-const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const { |
- return web_profiles_.get(); |
-} |
- |
-const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { |
- return credit_cards_.get(); |
-} |
- |
-void PersonalDataManager::Refresh() { |
- LoadProfiles(); |
- LoadCreditCards(); |
-} |
- |
-void PersonalDataManager::GetProfileSuggestions( |
- AutofillFieldType type, |
- const base::string16& field_contents, |
- bool field_is_autofilled, |
- std::vector<AutofillFieldType> other_field_types, |
- std::vector<base::string16>* values, |
- std::vector<base::string16>* labels, |
- std::vector<base::string16>* icons, |
- std::vector<GUIDPair>* guid_pairs) { |
- values->clear(); |
- labels->clear(); |
- icons->clear(); |
- guid_pairs->clear(); |
- |
- const std::vector<AutofillProfile*>& profiles = GetProfiles(); |
- std::vector<AutofillProfile*> matched_profiles; |
- for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin(); |
- iter != profiles.end(); ++iter) { |
- AutofillProfile* profile = *iter; |
- |
- // The value of the stored data for this field type in the |profile|. |
- std::vector<base::string16> multi_values; |
- profile->GetMultiInfo(type, app_locale_, &multi_values); |
- |
- for (size_t i = 0; i < multi_values.size(); ++i) { |
- if (!field_is_autofilled) { |
- // Suggest data that starts with what the user has typed. |
- if (!multi_values[i].empty() && |
- StartsWith(multi_values[i], field_contents, false)) { |
- matched_profiles.push_back(profile); |
- values->push_back(multi_values[i]); |
- guid_pairs->push_back(GUIDPair(profile->guid(), i)); |
- } |
- } else { |
- if (multi_values[i].empty()) |
- continue; |
- |
- base::string16 profile_value_lower_case( |
- StringToLowerASCII(multi_values[i])); |
- base::string16 field_value_lower_case( |
- StringToLowerASCII(field_contents)); |
- // Phone numbers could be split in US forms, so field value could be |
- // either prefix or suffix of the phone. |
- bool matched_phones = false; |
- if (type == PHONE_HOME_NUMBER && !field_value_lower_case.empty() && |
- (profile_value_lower_case.find(field_value_lower_case) != |
- base::string16::npos)) { |
- matched_phones = true; |
- } |
- |
- // Suggest variants of the profile that's already been filled in. |
- if (matched_phones || |
- profile_value_lower_case == field_value_lower_case) { |
- for (size_t j = 0; j < multi_values.size(); ++j) { |
- if (!multi_values[j].empty()) { |
- values->push_back(multi_values[j]); |
- guid_pairs->push_back(GUIDPair(profile->guid(), j)); |
- } |
- } |
- |
- // We've added all the values for this profile so move on to the |
- // next. |
- break; |
- } |
- } |
- } |
- } |
- |
- if (!field_is_autofilled) { |
- AutofillProfile::CreateInferredLabels( |
- &matched_profiles, &other_field_types, |
- type, 1, labels); |
- } else { |
- // No sub-labels for previously filled fields. |
- labels->resize(values->size()); |
- } |
- |
- // No icons for profile suggestions. |
- icons->resize(values->size()); |
-} |
- |
-void PersonalDataManager::GetCreditCardSuggestions( |
- AutofillFieldType type, |
- const base::string16& field_contents, |
- std::vector<base::string16>* values, |
- std::vector<base::string16>* labels, |
- std::vector<base::string16>* icons, |
- std::vector<GUIDPair>* guid_pairs) { |
- values->clear(); |
- labels->clear(); |
- icons->clear(); |
- guid_pairs->clear(); |
- |
- const std::vector<CreditCard*>& credit_cards = GetCreditCards(); |
- for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); |
- iter != credit_cards.end(); ++iter) { |
- CreditCard* credit_card = *iter; |
- |
- // The value of the stored data for this field type in the |credit_card|. |
- base::string16 creditcard_field_value = |
- credit_card->GetInfo(type, app_locale_); |
- if (!creditcard_field_value.empty() && |
- StartsWith(creditcard_field_value, field_contents, false)) { |
- if (type == CREDIT_CARD_NUMBER) |
- creditcard_field_value = credit_card->ObfuscatedNumber(); |
- |
- base::string16 label; |
- if (credit_card->number().empty()) { |
- // If there is no CC number, return name to show something. |
- label = credit_card->GetInfo(CREDIT_CARD_NAME, app_locale_); |
- } else { |
- label = kCreditCardPrefix; |
- label.append(credit_card->LastFourDigits()); |
- } |
- |
- values->push_back(creditcard_field_value); |
- labels->push_back(label); |
- icons->push_back(UTF8ToUTF16(credit_card->type())); |
- guid_pairs->push_back(GUIDPair(credit_card->guid(), 0)); |
- } |
- } |
-} |
- |
-bool PersonalDataManager::IsAutofillEnabled() const { |
- return user_prefs::UserPrefs::Get(browser_context_)->GetBoolean( |
- prefs::kAutofillEnabled); |
-} |
- |
-// static |
-bool PersonalDataManager::IsValidLearnableProfile( |
- const AutofillProfile& profile, |
- const std::string& app_locale) { |
- if (!IsMinimumAddress(profile, app_locale)) |
- return false; |
- |
- base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS); |
- if (!email.empty() && !autofill::IsValidEmailAddress(email)) |
- return false; |
- |
- // Reject profiles with invalid US state information. |
- base::string16 state = profile.GetRawInfo(ADDRESS_HOME_STATE); |
- if (profile.GetRawInfo(ADDRESS_HOME_COUNTRY) == ASCIIToUTF16("US") && |
- !state.empty() && !IsValidState(state)) { |
- return false; |
- } |
- |
- // Reject profiles with invalid US zip information. |
- base::string16 zip = profile.GetRawInfo(ADDRESS_HOME_ZIP); |
- if (profile.GetRawInfo(ADDRESS_HOME_COUNTRY) == ASCIIToUTF16("US") && |
- !zip.empty() && !autofill::IsValidZip(zip)) |
- return false; |
- |
- return true; |
-} |
- |
-// static |
-bool PersonalDataManager::MergeProfile( |
- const AutofillProfile& new_profile, |
- const std::vector<AutofillProfile*>& existing_profiles, |
- const std::string& app_locale, |
- std::vector<AutofillProfile>* merged_profiles) { |
- merged_profiles->clear(); |
- |
- // Set to true if |existing_profiles| already contains an equivalent profile. |
- bool matching_profile_found = false; |
- |
- // If we have already saved this address, merge in any missing values. |
- // Only merge with the first match. |
- for (std::vector<AutofillProfile*>::const_iterator iter = |
- existing_profiles.begin(); |
- iter != existing_profiles.end(); ++iter) { |
- AutofillProfile* existing_profile = *iter; |
- if (!matching_profile_found && |
- !new_profile.PrimaryValue().empty() && |
- StringToLowerASCII(existing_profile->PrimaryValue()) == |
- StringToLowerASCII(new_profile.PrimaryValue())) { |
- // Unverified profiles should always be updated with the newer data, |
- // whereas verified profiles should only ever be overwritten by verified |
- // data. If an automatically aggregated profile would overwrite a |
- // verified profile, just drop it. |
- matching_profile_found = true; |
- if (!existing_profile->IsVerified() || new_profile.IsVerified()) |
- existing_profile->OverwriteWithOrAddTo(new_profile, app_locale); |
- } |
- merged_profiles->push_back(*existing_profile); |
- } |
- |
- // If the new profile was not merged with an existing one, add it to the list. |
- if (!matching_profile_found) |
- merged_profiles->push_back(new_profile); |
- |
- return matching_profile_found; |
-} |
- |
-void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- // Remove empty profiles from input. |
- for (std::vector<AutofillProfile>::iterator it = profiles->begin(); |
- it != profiles->end();) { |
- if (it->IsEmpty(app_locale_)) |
- profiles->erase(it); |
- else |
- it++; |
- } |
- |
- // Ensure that profile labels are up to date. Currently, sync relies on |
- // labels to identify a profile. |
- // TODO(dhollowa): We need to deprecate labels and update the way sync |
- // identifies profiles. |
- std::vector<AutofillProfile*> profile_pointers(profiles->size()); |
- std::transform(profiles->begin(), profiles->end(), profile_pointers.begin(), |
- address_of<AutofillProfile>); |
- AutofillProfile::AdjustInferredLabels(&profile_pointers); |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- // Any profiles that are not in the new profile list should be removed from |
- // the web database. |
- for (std::vector<AutofillProfile*>::const_iterator iter = |
- web_profiles_.begin(); |
- iter != web_profiles_.end(); ++iter) { |
- if (!FindByGUID<AutofillProfile>(*profiles, (*iter)->guid())) |
- autofill_data->RemoveAutofillProfile((*iter)->guid()); |
- } |
- |
- // Update the web database with the existing profiles. |
- for (std::vector<AutofillProfile>::iterator iter = profiles->begin(); |
- iter != profiles->end(); ++iter) { |
- if (FindByGUID<AutofillProfile>(web_profiles_, iter->guid())) |
- autofill_data->UpdateAutofillProfile(*iter); |
- } |
- |
- // Add the new profiles to the web database. Don't add a duplicate. |
- for (std::vector<AutofillProfile>::iterator iter = profiles->begin(); |
- iter != profiles->end(); ++iter) { |
- if (!FindByGUID<AutofillProfile>(web_profiles_, iter->guid()) && |
- !FindByContents(web_profiles_, *iter)) |
- autofill_data->AddAutofillProfile(*iter); |
- } |
- |
- // Copy in the new profiles. |
- web_profiles_.clear(); |
- for (std::vector<AutofillProfile>::iterator iter = profiles->begin(); |
- iter != profiles->end(); ++iter) { |
- web_profiles_.push_back(new AutofillProfile(*iter)); |
- } |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-void PersonalDataManager::SetCreditCards( |
- std::vector<CreditCard>* credit_cards) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- // Remove empty credit cards from input. |
- for (std::vector<CreditCard>::iterator it = credit_cards->begin(); |
- it != credit_cards->end();) { |
- if (it->IsEmpty(app_locale_)) |
- credit_cards->erase(it); |
- else |
- it++; |
- } |
- |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) |
- return; |
- |
- // Any credit cards that are not in the new credit card list should be |
- // removed. |
- for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin(); |
- iter != credit_cards_.end(); ++iter) { |
- if (!FindByGUID<CreditCard>(*credit_cards, (*iter)->guid())) |
- autofill_data->RemoveCreditCard((*iter)->guid()); |
- } |
- |
- // Update the web database with the existing credit cards. |
- for (std::vector<CreditCard>::iterator iter = credit_cards->begin(); |
- iter != credit_cards->end(); ++iter) { |
- if (FindByGUID<CreditCard>(credit_cards_, iter->guid())) |
- autofill_data->UpdateCreditCard(*iter); |
- } |
- |
- // Add the new credit cards to the web database. Don't add a duplicate. |
- for (std::vector<CreditCard>::iterator iter = credit_cards->begin(); |
- iter != credit_cards->end(); ++iter) { |
- if (!FindByGUID<CreditCard>(credit_cards_, iter->guid()) && |
- !FindByContents(credit_cards_, *iter)) |
- autofill_data->AddCreditCard(*iter); |
- } |
- |
- // Copy in the new credit cards. |
- credit_cards_.clear(); |
- for (std::vector<CreditCard>::iterator iter = credit_cards->begin(); |
- iter != credit_cards->end(); ++iter) { |
- credit_cards_.push_back(new CreditCard(*iter)); |
- } |
- |
- // Refresh our local cache and send notifications to observers. |
- Refresh(); |
-} |
- |
-void PersonalDataManager::LoadProfiles() { |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) { |
- NOTREACHED(); |
- return; |
- } |
- |
- CancelPendingQuery(&pending_profiles_query_); |
- |
- pending_profiles_query_ = autofill_data->GetAutofillProfiles(this); |
-} |
- |
-// Win and Linux implementations do nothing. Mac and Android implementations |
-// fill in the contents of |auxiliary_profiles_|. |
-#if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
-void PersonalDataManager::LoadAuxiliaryProfiles() { |
-} |
-#endif |
- |
-void PersonalDataManager::LoadCreditCards() { |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) { |
- NOTREACHED(); |
- return; |
- } |
- |
- CancelPendingQuery(&pending_creditcards_query_); |
- |
- pending_creditcards_query_ = autofill_data->GetCreditCards(this); |
-} |
- |
-void PersonalDataManager::ReceiveLoadedProfiles(WebDataServiceBase::Handle h, |
- const WDTypedResult* result) { |
- DCHECK_EQ(pending_profiles_query_, h); |
- |
- pending_profiles_query_ = 0; |
- web_profiles_.clear(); |
- |
- const WDResult<std::vector<AutofillProfile*> >* r = |
- static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result); |
- |
- std::vector<AutofillProfile*> profiles = r->GetValue(); |
- for (std::vector<AutofillProfile*>::iterator iter = profiles.begin(); |
- iter != profiles.end(); ++iter) { |
- web_profiles_.push_back(*iter); |
- } |
- |
- LogProfileCount(); |
-} |
- |
-void PersonalDataManager::ReceiveLoadedCreditCards( |
- WebDataServiceBase::Handle h, const WDTypedResult* result) { |
- DCHECK_EQ(pending_creditcards_query_, h); |
- |
- pending_creditcards_query_ = 0; |
- credit_cards_.clear(); |
- |
- const WDResult<std::vector<CreditCard*> >* r = |
- static_cast<const WDResult<std::vector<CreditCard*> >*>(result); |
- |
- std::vector<CreditCard*> credit_cards = r->GetValue(); |
- for (std::vector<CreditCard*>::iterator iter = credit_cards.begin(); |
- iter != credit_cards.end(); ++iter) { |
- credit_cards_.push_back(*iter); |
- } |
-} |
- |
-void PersonalDataManager::CancelPendingQuery( |
- WebDataServiceBase::Handle* handle) { |
- if (*handle) { |
- scoped_refptr<AutofillWebDataService> autofill_data( |
- AutofillWebDataService::FromBrowserContext(browser_context_)); |
- if (!autofill_data.get()) { |
- NOTREACHED(); |
- return; |
- } |
- autofill_data->CancelRequest(*handle); |
- } |
- *handle = 0; |
-} |
- |
-void PersonalDataManager::SaveImportedProfile( |
- const AutofillProfile& imported_profile) { |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- // Don't save a web profile if the data in the profile is a subset of an |
- // auxiliary profile. |
- for (std::vector<AutofillProfile*>::const_iterator iter = |
- auxiliary_profiles_.begin(); |
- iter != auxiliary_profiles_.end(); ++iter) { |
- if (imported_profile.IsSubsetOf(**iter, app_locale_)) |
- return; |
- } |
- |
- std::vector<AutofillProfile> profiles; |
- MergeProfile(imported_profile, web_profiles_.get(), app_locale_, &profiles); |
- SetProfiles(&profiles); |
-} |
- |
- |
-void PersonalDataManager::SaveImportedCreditCard( |
- const CreditCard& imported_card) { |
- DCHECK(!imported_card.number().empty()); |
- if (browser_context_->IsOffTheRecord()) |
- return; |
- |
- // Set to true if |imported_card| is merged into the credit card list. |
- bool merged = false; |
- |
- std::vector<CreditCard> credit_cards; |
- for (std::vector<CreditCard*>::const_iterator card = credit_cards_.begin(); |
- card != credit_cards_.end(); |
- ++card) { |
- // If |imported_card| has not yet been merged, check whether it should be |
- // with the current |card|. |
- if (!merged && (*card)->UpdateFromImportedCard(imported_card, app_locale_)) |
- merged = true; |
- |
- credit_cards.push_back(**card); |
- } |
- |
- if (!merged) |
- credit_cards.push_back(imported_card); |
- |
- SetCreditCards(&credit_cards); |
-} |
- |
-void PersonalDataManager::LogProfileCount() const { |
- if (!has_logged_profile_count_) { |
- metric_logger_->LogStoredProfileCount(web_profiles_.size()); |
- has_logged_profile_count_ = true; |
- } |
-} |
- |
-const AutofillMetrics* PersonalDataManager::metric_logger() const { |
- return metric_logger_.get(); |
-} |
- |
-void PersonalDataManager::set_metric_logger( |
- const AutofillMetrics* metric_logger) { |
- metric_logger_.reset(metric_logger); |
-} |
- |
-void PersonalDataManager::set_browser_context( |
- content::BrowserContext* context) { |
- browser_context_ = context; |
-} |
- |
-} // namespace autofill |