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

Unified Diff: components/autofill/browser/personal_data_manager.cc

Issue 17392006: In components/autofill, move browser/ to core/browser/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to fix conflicts Created 7 years, 6 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 side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « components/autofill/browser/personal_data_manager.h ('k') | components/autofill/browser/personal_data_manager_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698