Home | History | Annotate | Download | only in browser
      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.
      4 
      5 #include "components/autofill/core/browser/personal_data_manager.h"
      6 
      7 #include <algorithm>
      8 #include <functional>
      9 #include <iterator>
     10 
     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"
     30 
     31 namespace autofill {
     32 namespace {
     33 
     34 using ::i18n::addressinput::AddressField;
     35 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine;
     36 using ::i18n::addressinput::STREET_ADDRESS;
     37 
     38 const base::string16::value_type kCreditCardPrefix[] = {'*', 0};
     39 
     40 template<typename T>
     41 class FormGroupMatchesByGUIDFunctor {
     42  public:
     43   explicit FormGroupMatchesByGUIDFunctor(const std::string& guid)
     44       : guid_(guid) {
     45   }
     46 
     47   bool operator()(const T& form_group) {
     48     return form_group.guid() == guid_;
     49   }
     50 
     51   bool operator()(const T* form_group) {
     52     return form_group->guid() == guid_;
     53   }
     54 
     55  private:
     56   const std::string guid_;
     57 };
     58 
     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(),
     63                       container.end(),
     64                       FormGroupMatchesByGUIDFunctor<T>(guid));
     65 }
     66 
     67 template<typename T, typename C>
     68 bool FindByGUID(const C& container, const std::string& guid) {
     69   return FindElementByGUID<T>(container, guid) != container.end();
     70 }
     71 
     72 template<typename T>
     73 class IsEmptyFunctor {
     74  public:
     75   explicit IsEmptyFunctor(const std::string& app_locale)
     76       : app_locale_(app_locale) {
     77   }
     78 
     79   bool operator()(const T& form_group) {
     80     return form_group.IsEmpty(app_locale_);
     81   }
     82 
     83  private:
     84   const std::string app_locale_;
     85 };
     86 
     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())
     96     return false;
     97 
     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);
    102 
    103   AutofillCountry country(country_code, app_locale);
    104 
    105   if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty())
    106     return false;
    107 
    108   if (country.requires_state() &&
    109       profile.GetRawInfo(ADDRESS_HOME_STATE).empty())
    110     return false;
    111 
    112   if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty())
    113     return false;
    114 
    115   return true;
    116 }
    117 
    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)
    131     return false;
    132 
    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))
    136     return false;
    137 
    138   return true;
    139 }
    140 
    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;
    145 }
    146 
    147 }  // namespace
    148 
    149 PersonalDataManager::PersonalDataManager(const std::string& app_locale)
    150     : database_(NULL),
    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),
    156       pref_service_(NULL),
    157       is_off_the_record_(false),
    158       has_logged_profile_count_(false) {}
    159 
    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;
    166 
    167   if (!is_off_the_record_)
    168     metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled());
    169 
    170   // WebDataService may not be available in tests.
    171   if (!database_.get())
    172     return;
    173 
    174   LoadProfiles();
    175   LoadCreditCards();
    176 
    177   database_->AddObserver(this);
    178 }
    179 
    180 PersonalDataManager::~PersonalDataManager() {
    181   CancelPendingQuery(&pending_profiles_query_);
    182   CancelPendingQuery(&pending_creditcards_query_);
    183 
    184   if (database_.get())
    185     database_->RemoveObserver(this);
    186 }
    187 
    188 void PersonalDataManager::OnWebDataServiceRequestDone(
    189     WebDataServiceBase::Handle h,
    190     const WDTypedResult* result) {
    191   DCHECK(pending_profiles_query_ || pending_creditcards_query_);
    192 
    193   if (!result) {
    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;
    199     return;
    200   }
    201 
    202   switch (result->GetType()) {
    203     case AUTOFILL_PROFILES_RESULT:
    204       ReceiveLoadedProfiles(h, result);
    205       break;
    206     case AUTOFILL_CREDITCARDS_RESULT:
    207       ReceiveLoadedCreditCards(h, result);
    208       break;
    209     default:
    210       NOTREACHED();
    211   }
    212 
    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();
    217   }
    218 }
    219 
    220 void PersonalDataManager::AutofillMultipleChanged() {
    221   Refresh();
    222 }
    223 
    224 void PersonalDataManager::AddObserver(PersonalDataManagerObserver* observer) {
    225   observers_.AddObserver(observer);
    226 }
    227 
    228 void PersonalDataManager::RemoveObserver(
    229     PersonalDataManagerObserver* observer) {
    230   observers_.RemoveObserver(observer);
    231 }
    232 
    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);
    238 
    239   const std::string origin = form.source_url().spec();
    240   imported_profile->set_origin(origin);
    241   local_imported_credit_card->set_origin(origin);
    242 
    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;
    246 
    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;
    251 
    252   // We only set complete phone, so aggregate phone parts in these vars and set
    253   // complete at the end.
    254   PhoneNumber::PhoneCombineHelper home;
    255 
    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);
    260 
    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())
    264       continue;
    265 
    266     AutofillType field_type = field->Type();
    267     ServerFieldType server_field_type = field_type.GetStorableType();
    268     FieldTypeGroup group(field_type.group());
    269 
    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
    272     // invalid.
    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();
    277         break;
    278       }
    279     }
    280 
    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();
    286       break;
    287     }
    288 
    289     types_seen.insert(server_field_type);
    290 
    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);
    295       } else {
    296         local_imported_credit_card->SetInfo(field_type, value, app_locale_);
    297       }
    298       ++importable_credit_card_fields;
    299     } else {
    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_);
    306 
    307       // Reject profiles with invalid country information.
    308       if (server_field_type == ADDRESS_HOME_COUNTRY &&
    309           !value.empty() &&
    310           imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) {
    311         imported_profile.reset();
    312         break;
    313       }
    314     }
    315   }
    316 
    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),
    323                                    constructed_number,
    324                                    app_locale_)) {
    325       imported_profile.reset();
    326     }
    327   }
    328 
    329   // Reject the profile if minimum address and validation requirements are not
    330   // met.
    331   if (imported_profile.get() &&
    332       !IsValidLearnableProfile(*imported_profile, app_locale_))
    333     imported_profile.reset();
    334 
    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();
    340   }
    341 
    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();
    348          ++iter) {
    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(),
    353                                       app_locale_)) {
    354         merged_credit_card = true;
    355         UpdateCreditCard(card);
    356         local_imported_credit_card.reset();
    357         break;
    358       }
    359     }
    360   }
    361 
    362   if (imported_profile.get()) {
    363     // We always save imported profiles.
    364     SaveImportedProfile(*imported_profile);
    365   }
    366   *imported_credit_card = local_imported_credit_card.Pass();
    367 
    368   if (imported_profile.get() || *imported_credit_card || merged_credit_card)
    369     return true;
    370 
    371   FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
    372                     OnInsufficientFormData());
    373   return false;
    374 }
    375 
    376 void PersonalDataManager::AddProfile(const AutofillProfile& profile) {
    377   if (is_off_the_record_)
    378     return;
    379 
    380   if (profile.IsEmpty(app_locale_))
    381     return;
    382 
    383   // Don't add an existing profile.
    384   if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()))
    385     return;
    386 
    387   if (!database_.get())
    388     return;
    389 
    390   // Don't add a duplicate.
    391   if (FindByContents(web_profiles_, profile))
    392     return;
    393 
    394   // Add the new profile to the web database.
    395   database_->AddAutofillProfile(profile);
    396 
    397   // Refresh our local cache and send notifications to observers.
    398   Refresh();
    399 }
    400 
    401 void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
    402   if (is_off_the_record_)
    403     return;
    404 
    405   AutofillProfile* existing_profile = GetProfileByGUID(profile.guid());
    406   if (!existing_profile)
    407     return;
    408 
    409   // Don't overwrite the origin for a profile that is already stored.
    410   if (existing_profile->EqualsSansOrigin(profile))
    411     return;
    412 
    413   if (profile.IsEmpty(app_locale_)) {
    414     RemoveByGUID(profile.guid());
    415     return;
    416   }
    417 
    418   if (!database_.get())
    419     return;
    420 
    421   // Make the update.
    422   database_->UpdateAutofillProfile(profile);
    423 
    424   // Refresh our local cache and send notifications to observers.
    425   Refresh();
    426 }
    427 
    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;
    434 }
    435 
    436 void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) {
    437   if (is_off_the_record_)
    438     return;
    439 
    440   if (credit_card.IsEmpty(app_locale_))
    441     return;
    442 
    443   if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid()))
    444     return;
    445 
    446   if (!database_.get())
    447     return;
    448 
    449   // Don't add a duplicate.
    450   if (FindByContents(credit_cards_, credit_card))
    451     return;
    452 
    453   // Add the new credit card to the web database.
    454   database_->AddCreditCard(credit_card);
    455 
    456   // Refresh our local cache and send notifications to observers.
    457   Refresh();
    458 }
    459 
    460 void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
    461   if (is_off_the_record_)
    462     return;
    463 
    464   CreditCard* existing_credit_card = GetCreditCardByGUID(credit_card.guid());
    465   if (!existing_credit_card)
    466     return;
    467 
    468   // Don't overwrite the origin for a credit card that is already stored.
    469   if (existing_credit_card->Compare(credit_card) == 0)
    470     return;
    471 
    472   if (credit_card.IsEmpty(app_locale_)) {
    473     RemoveByGUID(credit_card.guid());
    474     return;
    475   }
    476 
    477   if (!database_.get())
    478     return;
    479 
    480   // Make the update.
    481   database_->UpdateCreditCard(credit_card);
    482 
    483   // Refresh our local cache and send notifications to observers.
    484   Refresh();
    485 }
    486 
    487 void PersonalDataManager::RemoveByGUID(const std::string& guid) {
    488   if (is_off_the_record_)
    489     return;
    490 
    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)
    495     return;
    496 
    497   if (!database_.get())
    498     return;
    499 
    500   if (is_credit_card)
    501     database_->RemoveCreditCard(guid);
    502   else
    503     database_->RemoveAutofillProfile(guid);
    504 
    505   // Refresh our local cache and send notifications to observers.
    506   Refresh();
    507 }
    508 
    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;
    514 }
    515 
    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);
    522   }
    523 
    524   for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin();
    525        iter != credit_cards_.end(); ++iter) {
    526     (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
    527   }
    528 }
    529 
    530 bool PersonalDataManager::IsDataLoaded() const {
    531   return is_data_loaded_;
    532 }
    533 
    534 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const {
    535   return GetProfiles(false);
    536 }
    537 
    538 const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const {
    539   return web_profiles_.get();
    540 }
    541 
    542 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
    543   return credit_cards_.get();
    544 }
    545 
    546 void PersonalDataManager::Refresh() {
    547   LoadProfiles();
    548   LoadCreditCards();
    549 }
    550 
    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) {
    561   values->clear();
    562   labels->clear();
    563   icons->clear();
    564   guid_pairs->clear();
    565 
    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;
    571 
    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));
    582     } else {
    583       profile->GetMultiInfo(type, app_locale_, &multi_values);
    584     }
    585 
    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);
    590 
    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));
    599         }
    600       } else {
    601         if (multi_values[i].empty())
    602           continue;
    603 
    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;
    616         }
    617 
    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));
    625             }
    626           }
    627 
    628           // We've added all the values for this profile so move on to the
    629           // next.
    630           break;
    631         }
    632       }
    633     }
    634   }
    635 
    636   if (!field_is_autofilled) {
    637     AutofillProfile::CreateInferredLabels(
    638         matched_profiles, &other_field_types,
    639         type.GetStorableType(), 1, app_locale_, labels);
    640   } else {
    641     // No sub-labels for previously filled fields.
    642     labels->resize(values->size());
    643   }
    644 
    645   // No icons for profile suggestions.
    646   icons->resize(values->size());
    647 }
    648 
    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) {
    656   values->clear();
    657   labels->clear();
    658   icons->clear();
    659   guid_pairs->clear();
    660 
    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;
    665 
    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();
    673 
    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) {
    683           label =
    684               credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_);
    685         }
    686       } else {
    687         label = kCreditCardPrefix;
    688         label.append(credit_card->LastFourDigits());
    689       }
    690 
    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));
    695     }
    696   }
    697 }
    698 
    699 bool PersonalDataManager::IsAutofillEnabled() const {
    700   DCHECK(pref_service_);
    701   return pref_service_->GetBoolean(prefs::kAutofillEnabled);
    702 }
    703 
    704 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const {
    705   return base::CountryCodeForCurrentTimezone();
    706 }
    707 
    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.
    712   if (pref_service_) {
    713     enabled_pref_->Init(prefs::kAutofillEnabled, pref_service_,
    714         base::Bind(&PersonalDataManager::EnabledPrefChanged,
    715                    base::Unretained(this)));
    716   }
    717 }
    718 
    719 // static
    720 bool PersonalDataManager::IsValidLearnableProfile(
    721     const AutofillProfile& profile,
    722     const std::string& app_locale) {
    723   if (!IsMinimumAddress(profile, app_locale))
    724     return false;
    725 
    726   base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS);
    727   if (!email.empty() && !IsValidEmailAddress(email))
    728     return false;
    729 
    730   // Reject profiles with invalid US state information.
    731   if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE))
    732     return false;
    733 
    734   // Reject profiles with invalid US zip information.
    735   if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP))
    736     return false;
    737 
    738   return true;
    739 }
    740 
    741 // static
    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();
    748 
    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();
    752 
    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);
    771     }
    772     merged_profiles->push_back(*existing_profile);
    773   }
    774 
    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);
    778 
    779   return guid;
    780 }
    781 
    782 bool PersonalDataManager::IsCountryOfInterest(const std::string& country_code)
    783     const {
    784   DCHECK_EQ(2U, country_code.size());
    785 
    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))));
    791   }
    792 
    793   std::string timezone_country = CountryCodeForCurrentTimezone();
    794   if (!timezone_country.empty())
    795     country_codes.push_back(base::StringToLowerASCII(timezone_country));
    796 
    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())));
    801   }
    802 
    803   return std::find(country_codes.begin(), country_codes.end(),
    804                    base::StringToLowerASCII(country_code)) !=
    805                        country_codes.end();
    806 }
    807 
    808 const std::string& PersonalDataManager::GetDefaultCountryCodeForNewAddress()
    809     const {
    810   if (default_country_code_.empty())
    811     default_country_code_ = MostCommonCountryCodeFromProfiles();
    812 
    813   // Failing that, guess based on system timezone.
    814   if (default_country_code_.empty())
    815     default_country_code_ = CountryCodeForCurrentTimezone();
    816 
    817   // Failing that, guess based on locale.
    818   if (default_country_code_.empty())
    819     default_country_code_ = AutofillCountry::CountryCodeForLocale(app_locale());
    820 
    821   return default_country_code_;
    822 }
    823 
    824 void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
    825   if (is_off_the_record_)
    826     return;
    827 
    828   // Remove empty profiles from input.
    829   profiles->erase(std::remove_if(profiles->begin(), profiles->end(),
    830                                  IsEmptyFunctor<AutofillProfile>(app_locale_)),
    831                   profiles->end());
    832 
    833   if (!database_.get())
    834     return;
    835 
    836   // Any profiles that are not in the new profile list should be removed from
    837   // the web database.
    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());
    843   }
    844 
    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);
    850   }
    851 
    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);
    858   }
    859 
    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));
    865   }
    866 
    867   // Refresh our local cache and send notifications to observers.
    868   Refresh();
    869 }
    870 
    871 void PersonalDataManager::SetCreditCards(
    872     std::vector<CreditCard>* credit_cards) {
    873   if (is_off_the_record_)
    874     return;
    875 
    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());
    880 
    881   if (!database_.get())
    882     return;
    883 
    884   // Any credit cards that are not in the new credit card list should be
    885   // removed.
    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());
    890   }
    891 
    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);
    897   }
    898 
    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);
    905   }
    906 
    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));
    912   }
    913 
    914   // Refresh our local cache and send notifications to observers.
    915   Refresh();
    916 }
    917 
    918 void PersonalDataManager::LoadProfiles() {
    919   if (!database_.get()) {
    920     NOTREACHED();
    921     return;
    922   }
    923 
    924   CancelPendingQuery(&pending_profiles_query_);
    925 
    926   pending_profiles_query_ = database_->GetAutofillProfiles(this);
    927 }
    928 
    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 {
    933 }
    934 #endif
    935 
    936 void PersonalDataManager::LoadCreditCards() {
    937   if (!database_.get()) {
    938     NOTREACHED();
    939     return;
    940   }
    941 
    942   CancelPendingQuery(&pending_creditcards_query_);
    943 
    944   pending_creditcards_query_ = database_->GetCreditCards(this);
    945 }
    946 
    947 void PersonalDataManager::ReceiveLoadedProfiles(WebDataServiceBase::Handle h,
    948                                                 const WDTypedResult* result) {
    949   DCHECK_EQ(pending_profiles_query_, h);
    950 
    951   pending_profiles_query_ = 0;
    952   web_profiles_.clear();
    953 
    954   const WDResult<std::vector<AutofillProfile*> >* r =
    955       static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result);
    956 
    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);
    961   }
    962 
    963   LogProfileCount();
    964 }
    965 
    966 void PersonalDataManager::ReceiveLoadedCreditCards(
    967     WebDataServiceBase::Handle h, const WDTypedResult* result) {
    968   DCHECK_EQ(pending_creditcards_query_, h);
    969 
    970   pending_creditcards_query_ = 0;
    971   credit_cards_.clear();
    972 
    973   const WDResult<std::vector<CreditCard*> >* r =
    974       static_cast<const WDResult<std::vector<CreditCard*> >*>(result);
    975 
    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);
    980   }
    981 }
    982 
    983 void PersonalDataManager::CancelPendingQuery(
    984     WebDataServiceBase::Handle* handle) {
    985   if (*handle) {
    986     if (!database_.get()) {
    987       NOTREACHED();
    988       return;
    989     }
    990     database_->CancelRequest(*handle);
    991   }
    992   *handle = 0;
    993 }
    994 
    995 std::string PersonalDataManager::SaveImportedProfile(
    996     const AutofillProfile& imported_profile) {
    997   if (is_off_the_record_)
    998     return std::string();
    999 
   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();
   1007   }
   1008 
   1009   std::vector<AutofillProfile> profiles;
   1010   std::string guid =
   1011       MergeProfile(imported_profile, web_profiles_.get(), app_locale_,
   1012                    &profiles);
   1013   SetProfiles(&profiles);
   1014   return guid;
   1015 }
   1016 
   1017 void PersonalDataManager::NotifyPersonalDataChanged() {
   1018   FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
   1019                     OnPersonalDataChanged());
   1020 }
   1021 
   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();
   1027 
   1028   // Set to true if |imported_card| is merged into the credit card list.
   1029   bool merged = false;
   1030 
   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();
   1035        ++iter) {
   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();
   1041       merged = true;
   1042     }
   1043 
   1044     credit_cards.push_back(*card);
   1045   }
   1046 
   1047   if (!merged)
   1048     credit_cards.push_back(imported_card);
   1049 
   1050   SetCreditCards(&credit_cards);
   1051   return guid;
   1052 }
   1053 
   1054 void PersonalDataManager::LogProfileCount() const {
   1055   if (!has_logged_profile_count_) {
   1056     metric_logger_->LogStoredProfileCount(web_profiles_.size());
   1057     has_logged_profile_count_ = true;
   1058   }
   1059 }
   1060 
   1061 std::string PersonalDataManager::MostCommonCountryCodeFromProfiles() const {
   1062   if (!IsAutofillEnabled())
   1063     return std::string();
   1064 
   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)));
   1075 
   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;
   1080     }
   1081   }
   1082 
   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);
   1087     return iter->first;
   1088   }
   1089 
   1090   return std::string();
   1091 }
   1092 
   1093 void PersonalDataManager::EnabledPrefChanged() {
   1094   default_country_code_.clear();
   1095   NotifyPersonalDataChanged();
   1096 }
   1097 
   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();
   1103 #else
   1104   if (!pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled))
   1105     return web_profiles();
   1106 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
   1107 
   1108   profiles_.clear();
   1109 
   1110   // Populates |auxiliary_profiles_|.
   1111   LoadAuxiliaryProfiles(record_metrics);
   1112 
   1113   profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end());
   1114   profiles_.insert(
   1115       profiles_.end(), auxiliary_profiles_.begin(), auxiliary_profiles_.end());
   1116   return profiles_;
   1117 }
   1118 
   1119 }  // namespace autofill
   1120