personal_data_manager.cc revision f2477e01787aa58f445919b809d89e252beef54f
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/autofill-inl.h"
19#include "components/autofill/core/browser/autofill_country.h"
20#include "components/autofill/core/browser/autofill_field.h"
21#include "components/autofill/core/browser/form_structure.h"
22#include "components/autofill/core/browser/personal_data_manager_observer.h"
23#include "components/autofill/core/browser/phone_number.h"
24#include "components/autofill/core/browser/phone_number_i18n.h"
25#include "components/autofill/core/browser/validation.h"
26#include "components/autofill/core/common/autofill_pref_names.h"
27
28namespace autofill {
29namespace {
30
31const base::string16::value_type kCreditCardPrefix[] = {'*', 0};
32
33template<typename T>
34class FormGroupMatchesByGUIDFunctor {
35 public:
36  explicit FormGroupMatchesByGUIDFunctor(const std::string& guid)
37      : guid_(guid) {
38  }
39
40  bool operator()(const T& form_group) {
41    return form_group.guid() == guid_;
42  }
43
44  bool operator()(const T* form_group) {
45    return form_group->guid() == guid_;
46  }
47
48 private:
49  const std::string guid_;
50};
51
52template<typename T, typename C>
53typename C::const_iterator FindElementByGUID(const C& container,
54                                             const std::string& guid) {
55  return std::find_if(container.begin(),
56                      container.end(),
57                      FormGroupMatchesByGUIDFunctor<T>(guid));
58}
59
60template<typename T, typename C>
61bool FindByGUID(const C& container, const std::string& guid) {
62  return FindElementByGUID<T>(container, guid) != container.end();
63}
64
65template<typename T>
66class IsEmptyFunctor {
67 public:
68  explicit IsEmptyFunctor(const std::string& app_locale)
69      : app_locale_(app_locale) {
70  }
71
72  bool operator()(const T& form_group) {
73    return form_group.IsEmpty(app_locale_);
74  }
75
76 private:
77  const std::string app_locale_;
78};
79
80// Returns true if minimum requirements for import of a given |profile| have
81// been met.  An address submitted via a form must have at least the fields
82// required as determined by its country code.
83// No verification of validity of the contents is preformed. This is an
84// existence check only.
85bool IsMinimumAddress(const AutofillProfile& profile,
86                      const std::string& app_locale) {
87  // All countries require at least one address line.
88  if (profile.GetRawInfo(ADDRESS_HOME_LINE1).empty())
89    return false;
90
91  std::string country_code =
92      UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY));
93  if (country_code.empty())
94    country_code = AutofillCountry::CountryCodeForLocale(app_locale);
95
96  AutofillCountry country(country_code, app_locale);
97
98  if (country.requires_city() && profile.GetRawInfo(ADDRESS_HOME_CITY).empty())
99    return false;
100
101  if (country.requires_state() &&
102      profile.GetRawInfo(ADDRESS_HOME_STATE).empty())
103    return false;
104
105  if (country.requires_zip() && profile.GetRawInfo(ADDRESS_HOME_ZIP).empty())
106    return false;
107
108  return true;
109}
110
111// Return true if the |field_type| and |value| are valid within the context
112// of importing a form.
113bool IsValidFieldTypeAndValue(const std::set<ServerFieldType>& types_seen,
114                              ServerFieldType field_type,
115                              const base::string16& value) {
116  // Abandon the import if two fields of the same type are encountered.
117  // This indicates ambiguous data or miscategorization of types.
118  // Make an exception for PHONE_HOME_NUMBER however as both prefix and
119  // suffix are stored against this type, and for EMAIL_ADDRESS because it is
120  // common to see second 'confirm email address' fields on forms.
121  if (types_seen.count(field_type) &&
122      field_type != PHONE_HOME_NUMBER &&
123      field_type != EMAIL_ADDRESS)
124    return false;
125
126  // Abandon the import if an email address value shows up in a field that is
127  // not an email address.
128  if (field_type != EMAIL_ADDRESS && IsValidEmailAddress(value))
129    return false;
130
131  return true;
132}
133
134// A helper function for finding the maximum value in a string->int map.
135static bool CompareVotes(const std::pair<std::string, int>& a,
136                         const std::pair<std::string, int>& b) {
137  return a.second < b.second;
138}
139
140}  // namespace
141
142PersonalDataManager::PersonalDataManager(const std::string& app_locale)
143    : database_(NULL),
144      is_data_loaded_(false),
145      pending_profiles_query_(0),
146      pending_creditcards_query_(0),
147      app_locale_(app_locale),
148      metric_logger_(new AutofillMetrics),
149      is_off_the_record_(false),
150      has_logged_profile_count_(false) {}
151
152void PersonalDataManager::Init(scoped_refptr<AutofillWebDataService> database,
153                               PrefService* pref_service,
154                               bool is_off_the_record) {
155  database_ = database;
156  pref_service_ = pref_service;
157  is_off_the_record_ = is_off_the_record;
158
159  if (!is_off_the_record_)
160    metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled());
161
162  // WebDataService may not be available in tests.
163  if (!database_.get())
164    return;
165
166  LoadProfiles();
167  LoadCreditCards();
168
169  database_->AddObserver(this);
170}
171
172PersonalDataManager::~PersonalDataManager() {
173  CancelPendingQuery(&pending_profiles_query_);
174  CancelPendingQuery(&pending_creditcards_query_);
175
176  if (database_.get())
177    database_->RemoveObserver(this);
178}
179
180void PersonalDataManager::OnWebDataServiceRequestDone(
181    WebDataServiceBase::Handle h,
182    const WDTypedResult* result) {
183  DCHECK(pending_profiles_query_ || pending_creditcards_query_);
184
185  if (!result) {
186    // Error from the web database.
187    if (h == pending_creditcards_query_)
188      pending_creditcards_query_ = 0;
189    else if (h == pending_profiles_query_)
190      pending_profiles_query_ = 0;
191    return;
192  }
193
194  switch (result->GetType()) {
195    case AUTOFILL_PROFILES_RESULT:
196      ReceiveLoadedProfiles(h, result);
197      break;
198    case AUTOFILL_CREDITCARDS_RESULT:
199      ReceiveLoadedCreditCards(h, result);
200      break;
201    default:
202      NOTREACHED();
203  }
204
205  // If both requests have responded, then all personal data is loaded.
206  if (pending_profiles_query_ == 0 && pending_creditcards_query_ == 0) {
207    is_data_loaded_ = true;
208    FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
209                      OnPersonalDataChanged());
210  }
211}
212
213void PersonalDataManager::AutofillMultipleChanged() {
214  Refresh();
215}
216
217void PersonalDataManager::AddObserver(PersonalDataManagerObserver* observer) {
218  observers_.AddObserver(observer);
219}
220
221void PersonalDataManager::RemoveObserver(
222    PersonalDataManagerObserver* observer) {
223  observers_.RemoveObserver(observer);
224}
225
226bool PersonalDataManager::ImportFormData(
227    const FormStructure& form,
228    scoped_ptr<CreditCard>* imported_credit_card) {
229  scoped_ptr<AutofillProfile> imported_profile(new AutofillProfile);
230  scoped_ptr<CreditCard> local_imported_credit_card(new CreditCard);
231
232  const std::string origin = form.source_url().spec();
233  imported_profile->set_origin(origin);
234  local_imported_credit_card->set_origin(origin);
235
236  // Parse the form and construct a profile based on the information that is
237  // possible to import.
238  int importable_credit_card_fields = 0;
239
240  // Detect and discard forms with multiple fields of the same type.
241  // TODO(isherman): Some types are overlapping but not equal, e.g. phone number
242  // parts, address parts.
243  std::set<ServerFieldType> types_seen;
244
245  // We only set complete phone, so aggregate phone parts in these vars and set
246  // complete at the end.
247  PhoneNumber::PhoneCombineHelper home;
248
249  for (size_t i = 0; i < form.field_count(); ++i) {
250    const AutofillField* field = form.field(i);
251    base::string16 value = CollapseWhitespace(field->value, false);
252
253    // If we don't know the type of the field, or the user hasn't entered any
254    // information into the field, then skip it.
255    if (!field->IsFieldFillable() || value.empty())
256      continue;
257
258    AutofillType field_type = field->Type();
259    ServerFieldType server_field_type = field_type.GetStorableType();
260    FieldTypeGroup group(field_type.group());
261
262    // There can be multiple email fields (e.g. in the case of 'confirm email'
263    // fields) but they must all contain the same value, else the profile is
264    // invalid.
265    if (server_field_type == EMAIL_ADDRESS) {
266      if (types_seen.count(server_field_type) &&
267          imported_profile->GetRawInfo(EMAIL_ADDRESS) != value) {
268        imported_profile.reset();
269        break;
270      }
271    }
272
273    // If the |field_type| and |value| don't pass basic validity checks then
274    // abandon the import.
275    if (!IsValidFieldTypeAndValue(types_seen, server_field_type, value)) {
276      imported_profile.reset();
277      local_imported_credit_card.reset();
278      break;
279    }
280
281    types_seen.insert(server_field_type);
282
283    if (group == CREDIT_CARD) {
284      if (LowerCaseEqualsASCII(field->form_control_type, "month")) {
285        DCHECK_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, server_field_type);
286        local_imported_credit_card->SetInfoForMonthInputType(value);
287      } else {
288        local_imported_credit_card->SetInfo(field_type, value, app_locale_);
289      }
290      ++importable_credit_card_fields;
291    } else {
292      // We need to store phone data in the variables, before building the whole
293      // number at the end. The rest of the fields are set "as is".
294      // If the fields are not the phone fields in question home.SetInfo() is
295      // going to return false.
296      if (!home.SetInfo(field_type, value))
297        imported_profile->SetInfo(field_type, value, app_locale_);
298
299      // Reject profiles with invalid country information.
300      if (server_field_type == ADDRESS_HOME_COUNTRY &&
301          !value.empty() &&
302          imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) {
303        imported_profile.reset();
304        break;
305      }
306    }
307  }
308
309  // Construct the phone number. Reject the profile if the number is invalid.
310  if (imported_profile.get() && !home.IsEmpty()) {
311    base::string16 constructed_number;
312    if (!home.ParseNumber(*imported_profile, app_locale_,
313                          &constructed_number) ||
314        !imported_profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
315                                   constructed_number,
316                                   app_locale_)) {
317      imported_profile.reset();
318    }
319  }
320
321  // Reject the profile if minimum address and validation requirements are not
322  // met.
323  if (imported_profile.get() &&
324      !IsValidLearnableProfile(*imported_profile, app_locale_))
325    imported_profile.reset();
326
327  // Reject the credit card if we did not detect enough filled credit card
328  // fields or if the credit card number does not seem to be valid.
329  if (local_imported_credit_card.get() &&
330      !local_imported_credit_card->IsComplete()) {
331    local_imported_credit_card.reset();
332  }
333
334  // Don't import if we already have this info.
335  // Don't present an infobar if we have already saved this card number.
336  bool merged_credit_card = false;
337  if (local_imported_credit_card.get()) {
338    for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
339         iter != credit_cards_.end();
340         ++iter) {
341      // Make a local copy so that the data in |credit_cards_| isn't modified
342      // directly by the UpdateFromImportedCard() call.
343      CreditCard card = **iter;
344      if (card.UpdateFromImportedCard(*local_imported_credit_card.get(),
345                                      app_locale_)) {
346        merged_credit_card = true;
347        UpdateCreditCard(card);
348        local_imported_credit_card.reset();
349        break;
350      }
351    }
352  }
353
354  if (imported_profile.get()) {
355    // We always save imported profiles.
356    SaveImportedProfile(*imported_profile);
357  }
358  *imported_credit_card = local_imported_credit_card.Pass();
359
360  if (imported_profile.get() || *imported_credit_card || merged_credit_card)
361    return true;
362
363  FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
364                    OnInsufficientFormData());
365  return false;
366}
367
368void PersonalDataManager::AddProfile(const AutofillProfile& profile) {
369  if (is_off_the_record_)
370    return;
371
372  if (profile.IsEmpty(app_locale_))
373    return;
374
375  // Don't add an existing profile.
376  if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()))
377    return;
378
379  if (!database_.get())
380    return;
381
382  // Don't add a duplicate.
383  if (FindByContents(web_profiles_, profile))
384    return;
385
386  // Add the new profile to the web database.
387  database_->AddAutofillProfile(profile);
388
389  // Refresh our local cache and send notifications to observers.
390  Refresh();
391}
392
393void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
394  if (is_off_the_record_)
395    return;
396
397  AutofillProfile* existing_profile = GetProfileByGUID(profile.guid());
398  if (!existing_profile)
399    return;
400
401  // Don't overwrite the origin for a profile that is already stored.
402  if (existing_profile->Compare(profile) == 0)
403    return;
404
405  if (profile.IsEmpty(app_locale_)) {
406    RemoveByGUID(profile.guid());
407    return;
408  }
409
410  if (!database_.get())
411    return;
412
413  // Make the update.
414  database_->UpdateAutofillProfile(profile);
415
416  // Refresh our local cache and send notifications to observers.
417  Refresh();
418}
419
420AutofillProfile* PersonalDataManager::GetProfileByGUID(
421    const std::string& guid) {
422  const std::vector<AutofillProfile*>& profiles = GetProfiles();
423  std::vector<AutofillProfile*>::const_iterator iter =
424      FindElementByGUID<AutofillProfile>(profiles, guid);
425  return (iter != profiles.end()) ? *iter : NULL;
426}
427
428void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) {
429  if (is_off_the_record_)
430    return;
431
432  if (credit_card.IsEmpty(app_locale_))
433    return;
434
435  if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid()))
436    return;
437
438  if (!database_.get())
439    return;
440
441  // Don't add a duplicate.
442  if (FindByContents(credit_cards_, credit_card))
443    return;
444
445  // Add the new credit card to the web database.
446  database_->AddCreditCard(credit_card);
447
448  // Refresh our local cache and send notifications to observers.
449  Refresh();
450}
451
452void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
453  if (is_off_the_record_)
454    return;
455
456  CreditCard* existing_credit_card = GetCreditCardByGUID(credit_card.guid());
457  if (!existing_credit_card)
458    return;
459
460  // Don't overwrite the origin for a credit card that is already stored.
461  if (existing_credit_card->Compare(credit_card) == 0)
462    return;
463
464  if (credit_card.IsEmpty(app_locale_)) {
465    RemoveByGUID(credit_card.guid());
466    return;
467  }
468
469  if (!database_.get())
470    return;
471
472  // Make the update.
473  database_->UpdateCreditCard(credit_card);
474
475  // Refresh our local cache and send notifications to observers.
476  Refresh();
477}
478
479void PersonalDataManager::RemoveByGUID(const std::string& guid) {
480  if (is_off_the_record_)
481    return;
482
483  bool is_credit_card = FindByGUID<CreditCard>(credit_cards_, guid);
484  bool is_profile = !is_credit_card &&
485      FindByGUID<AutofillProfile>(web_profiles_, guid);
486  if (!is_credit_card && !is_profile)
487    return;
488
489  if (!database_.get())
490    return;
491
492  if (is_credit_card)
493    database_->RemoveCreditCard(guid);
494  else
495    database_->RemoveAutofillProfile(guid);
496
497  // Refresh our local cache and send notifications to observers.
498  Refresh();
499}
500
501CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) {
502  const std::vector<CreditCard*>& credit_cards = GetCreditCards();
503  std::vector<CreditCard*>::const_iterator iter =
504      FindElementByGUID<CreditCard>(credit_cards, guid);
505  return (iter != credit_cards.end()) ? *iter : NULL;
506}
507
508void PersonalDataManager::GetNonEmptyTypes(
509    ServerFieldTypeSet* non_empty_types) {
510  const std::vector<AutofillProfile*>& profiles = GetProfiles();
511  for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
512       iter != profiles.end(); ++iter) {
513    (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
514  }
515
516  for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin();
517       iter != credit_cards_.end(); ++iter) {
518    (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
519  }
520}
521
522bool PersonalDataManager::IsDataLoaded() const {
523  return is_data_loaded_;
524}
525
526const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const {
527  if (!pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled)) {
528    return web_profiles();
529  }
530
531  profiles_.clear();
532
533  // Populates |auxiliary_profiles_|.
534  LoadAuxiliaryProfiles();
535
536  profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end());
537  profiles_.insert(profiles_.end(),
538      auxiliary_profiles_.begin(), auxiliary_profiles_.end());
539  return profiles_;
540}
541
542const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const {
543  return web_profiles_.get();
544}
545
546const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
547  return credit_cards_.get();
548}
549
550void PersonalDataManager::Refresh() {
551  LoadProfiles();
552  LoadCreditCards();
553}
554
555void PersonalDataManager::GetProfileSuggestions(
556    const AutofillType& type,
557    const base::string16& field_contents,
558    bool field_is_autofilled,
559    const std::vector<ServerFieldType>& other_field_types,
560    std::vector<base::string16>* values,
561    std::vector<base::string16>* labels,
562    std::vector<base::string16>* icons,
563    std::vector<GUIDPair>* guid_pairs) {
564  values->clear();
565  labels->clear();
566  icons->clear();
567  guid_pairs->clear();
568
569  const std::vector<AutofillProfile*>& profiles = GetProfiles();
570  std::vector<AutofillProfile*> matched_profiles;
571  for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
572       iter != profiles.end(); ++iter) {
573    AutofillProfile* profile = *iter;
574
575    // The value of the stored data for this field type in the |profile|.
576    std::vector<base::string16> multi_values;
577    profile->GetMultiInfo(type, app_locale_, &multi_values);
578
579    for (size_t i = 0; i < multi_values.size(); ++i) {
580      if (!field_is_autofilled) {
581        // Suggest data that starts with what the user has typed.
582        if (!multi_values[i].empty() &&
583            StartsWith(multi_values[i], field_contents, false)) {
584          matched_profiles.push_back(profile);
585          values->push_back(multi_values[i]);
586          guid_pairs->push_back(GUIDPair(profile->guid(), i));
587        }
588      } else {
589        if (multi_values[i].empty())
590          continue;
591
592        base::string16 profile_value_lower_case(
593            StringToLowerASCII(multi_values[i]));
594        base::string16 field_value_lower_case(
595            StringToLowerASCII(field_contents));
596        // Phone numbers could be split in US forms, so field value could be
597        // either prefix or suffix of the phone.
598        bool matched_phones = false;
599        if (type.GetStorableType() == PHONE_HOME_NUMBER &&
600            !field_value_lower_case.empty() &&
601            profile_value_lower_case.find(field_value_lower_case) !=
602                base::string16::npos) {
603          matched_phones = true;
604        }
605
606        // Suggest variants of the profile that's already been filled in.
607        if (matched_phones ||
608            profile_value_lower_case == field_value_lower_case) {
609          for (size_t j = 0; j < multi_values.size(); ++j) {
610            if (!multi_values[j].empty()) {
611              values->push_back(multi_values[j]);
612              guid_pairs->push_back(GUIDPair(profile->guid(), j));
613            }
614          }
615
616          // We've added all the values for this profile so move on to the
617          // next.
618          break;
619        }
620      }
621    }
622  }
623
624  if (!field_is_autofilled) {
625    AutofillProfile::CreateInferredLabels(
626        matched_profiles, &other_field_types,
627        type.GetStorableType(), 1, labels);
628  } else {
629    // No sub-labels for previously filled fields.
630    labels->resize(values->size());
631  }
632
633  // No icons for profile suggestions.
634  icons->resize(values->size());
635}
636
637void PersonalDataManager::GetCreditCardSuggestions(
638    const AutofillType& type,
639    const base::string16& field_contents,
640    std::vector<base::string16>* values,
641    std::vector<base::string16>* labels,
642    std::vector<base::string16>* icons,
643    std::vector<GUIDPair>* guid_pairs) {
644  values->clear();
645  labels->clear();
646  icons->clear();
647  guid_pairs->clear();
648
649  const std::vector<CreditCard*>& credit_cards = GetCreditCards();
650  for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
651       iter != credit_cards.end(); ++iter) {
652    CreditCard* credit_card = *iter;
653
654    // The value of the stored data for this field type in the |credit_card|.
655    base::string16 creditcard_field_value =
656        credit_card->GetInfo(type, app_locale_);
657    if (!creditcard_field_value.empty() &&
658        StartsWith(creditcard_field_value, field_contents, false)) {
659      if (type.GetStorableType() == CREDIT_CARD_NUMBER)
660        creditcard_field_value = credit_card->ObfuscatedNumber();
661
662      base::string16 label;
663      if (credit_card->number().empty()) {
664        // If there is no CC number, return name to show something.
665        label =
666            credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_);
667      } else {
668        label = kCreditCardPrefix;
669        label.append(credit_card->LastFourDigits());
670      }
671
672      values->push_back(creditcard_field_value);
673      labels->push_back(label);
674      icons->push_back(UTF8ToUTF16(credit_card->type()));
675      guid_pairs->push_back(GUIDPair(credit_card->guid(), 0));
676    }
677  }
678}
679
680bool PersonalDataManager::IsAutofillEnabled() const {
681  return pref_service_->GetBoolean(prefs::kAutofillEnabled);
682}
683
684// static
685bool PersonalDataManager::IsValidLearnableProfile(
686    const AutofillProfile& profile,
687    const std::string& app_locale) {
688  if (!IsMinimumAddress(profile, app_locale))
689    return false;
690
691  base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS);
692  if (!email.empty() && !IsValidEmailAddress(email))
693    return false;
694
695  // Reject profiles with invalid US state information.
696  if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE))
697    return false;
698
699  // Reject profiles with invalid US zip information.
700  if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP))
701    return false;
702
703  return true;
704}
705
706// static
707std::string PersonalDataManager::MergeProfile(
708    const AutofillProfile& new_profile,
709    const std::vector<AutofillProfile*>& existing_profiles,
710    const std::string& app_locale,
711    std::vector<AutofillProfile>* merged_profiles) {
712  merged_profiles->clear();
713
714  // Set to true if |existing_profiles| already contains an equivalent profile.
715  bool matching_profile_found = false;
716  std::string guid = new_profile.guid();
717
718  // If we have already saved this address, merge in any missing values.
719  // Only merge with the first match.
720  for (std::vector<AutofillProfile*>::const_iterator iter =
721           existing_profiles.begin();
722       iter != existing_profiles.end(); ++iter) {
723    AutofillProfile* existing_profile = *iter;
724    if (!matching_profile_found &&
725        !new_profile.PrimaryValue().empty() &&
726        StringToLowerASCII(existing_profile->PrimaryValue()) ==
727            StringToLowerASCII(new_profile.PrimaryValue())) {
728      // Unverified profiles should always be updated with the newer data,
729      // whereas verified profiles should only ever be overwritten by verified
730      // data.  If an automatically aggregated profile would overwrite a
731      // verified profile, just drop it.
732      matching_profile_found = true;
733      guid = existing_profile->guid();
734      if (!existing_profile->IsVerified() || new_profile.IsVerified())
735        existing_profile->OverwriteWithOrAddTo(new_profile, app_locale);
736    }
737    merged_profiles->push_back(*existing_profile);
738  }
739
740  // If the new profile was not merged with an existing one, add it to the list.
741  if (!matching_profile_found)
742    merged_profiles->push_back(new_profile);
743
744  return guid;
745}
746
747const std::string& PersonalDataManager::GetDefaultCountryCodeForNewAddress()
748    const {
749  if (default_country_code_.empty())
750    default_country_code_ = MostCommonCountryCodeFromProfiles();
751
752  // Failing that, guess based on system timezone.
753  if (default_country_code_.empty())
754    default_country_code_ = base::CountryCodeForCurrentTimezone();
755
756  // Failing that, guess based on locale.
757  if (default_country_code_.empty())
758    default_country_code_ = AutofillCountry::CountryCodeForLocale(app_locale());
759
760  return default_country_code_;
761}
762
763void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
764  if (is_off_the_record_)
765    return;
766
767  // Remove empty profiles from input.
768  profiles->erase(std::remove_if(profiles->begin(), profiles->end(),
769                                 IsEmptyFunctor<AutofillProfile>(app_locale_)),
770                  profiles->end());
771
772  if (!database_.get())
773    return;
774
775  // Any profiles that are not in the new profile list should be removed from
776  // the web database.
777  for (std::vector<AutofillProfile*>::const_iterator iter =
778           web_profiles_.begin();
779       iter != web_profiles_.end(); ++iter) {
780    if (!FindByGUID<AutofillProfile>(*profiles, (*iter)->guid()))
781      database_->RemoveAutofillProfile((*iter)->guid());
782  }
783
784  // Update the web database with the existing profiles.
785  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
786       iter != profiles->end(); ++iter) {
787    if (FindByGUID<AutofillProfile>(web_profiles_, iter->guid()))
788      database_->UpdateAutofillProfile(*iter);
789  }
790
791  // Add the new profiles to the web database.  Don't add a duplicate.
792  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
793       iter != profiles->end(); ++iter) {
794    if (!FindByGUID<AutofillProfile>(web_profiles_, iter->guid()) &&
795        !FindByContents(web_profiles_, *iter))
796      database_->AddAutofillProfile(*iter);
797  }
798
799  // Copy in the new profiles.
800  web_profiles_.clear();
801  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
802       iter != profiles->end(); ++iter) {
803    web_profiles_.push_back(new AutofillProfile(*iter));
804  }
805
806  // Refresh our local cache and send notifications to observers.
807  Refresh();
808}
809
810void PersonalDataManager::SetCreditCards(
811    std::vector<CreditCard>* credit_cards) {
812  if (is_off_the_record_)
813    return;
814
815  // Remove empty credit cards from input.
816  credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(),
817                                     IsEmptyFunctor<CreditCard>(app_locale_)),
818                      credit_cards->end());
819
820  if (!database_.get())
821    return;
822
823  // Any credit cards that are not in the new credit card list should be
824  // removed.
825  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
826       iter != credit_cards_.end(); ++iter) {
827    if (!FindByGUID<CreditCard>(*credit_cards, (*iter)->guid()))
828      database_->RemoveCreditCard((*iter)->guid());
829  }
830
831  // Update the web database with the existing credit cards.
832  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
833       iter != credit_cards->end(); ++iter) {
834    if (FindByGUID<CreditCard>(credit_cards_, iter->guid()))
835      database_->UpdateCreditCard(*iter);
836  }
837
838  // Add the new credit cards to the web database.  Don't add a duplicate.
839  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
840       iter != credit_cards->end(); ++iter) {
841    if (!FindByGUID<CreditCard>(credit_cards_, iter->guid()) &&
842        !FindByContents(credit_cards_, *iter))
843      database_->AddCreditCard(*iter);
844  }
845
846  // Copy in the new credit cards.
847  credit_cards_.clear();
848  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
849       iter != credit_cards->end(); ++iter) {
850    credit_cards_.push_back(new CreditCard(*iter));
851  }
852
853  // Refresh our local cache and send notifications to observers.
854  Refresh();
855}
856
857void PersonalDataManager::LoadProfiles() {
858  if (!database_.get()) {
859    NOTREACHED();
860    return;
861  }
862
863  CancelPendingQuery(&pending_profiles_query_);
864
865  pending_profiles_query_ = database_->GetAutofillProfiles(this);
866}
867
868// Win and Linux implementations do nothing. Mac and Android implementations
869// fill in the contents of |auxiliary_profiles_|.
870#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
871void PersonalDataManager::LoadAuxiliaryProfiles() const {
872}
873#endif
874
875void PersonalDataManager::LoadCreditCards() {
876  if (!database_.get()) {
877    NOTREACHED();
878    return;
879  }
880
881  CancelPendingQuery(&pending_creditcards_query_);
882
883  pending_creditcards_query_ = database_->GetCreditCards(this);
884}
885
886void PersonalDataManager::ReceiveLoadedProfiles(WebDataServiceBase::Handle h,
887                                                const WDTypedResult* result) {
888  DCHECK_EQ(pending_profiles_query_, h);
889
890  pending_profiles_query_ = 0;
891  web_profiles_.clear();
892
893  const WDResult<std::vector<AutofillProfile*> >* r =
894      static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result);
895
896  std::vector<AutofillProfile*> profiles = r->GetValue();
897  for (std::vector<AutofillProfile*>::iterator iter = profiles.begin();
898       iter != profiles.end(); ++iter) {
899    web_profiles_.push_back(*iter);
900  }
901
902  LogProfileCount();
903}
904
905void PersonalDataManager::ReceiveLoadedCreditCards(
906    WebDataServiceBase::Handle h, const WDTypedResult* result) {
907  DCHECK_EQ(pending_creditcards_query_, h);
908
909  pending_creditcards_query_ = 0;
910  credit_cards_.clear();
911
912  const WDResult<std::vector<CreditCard*> >* r =
913      static_cast<const WDResult<std::vector<CreditCard*> >*>(result);
914
915  std::vector<CreditCard*> credit_cards = r->GetValue();
916  for (std::vector<CreditCard*>::iterator iter = credit_cards.begin();
917       iter != credit_cards.end(); ++iter) {
918    credit_cards_.push_back(*iter);
919  }
920}
921
922void PersonalDataManager::CancelPendingQuery(
923    WebDataServiceBase::Handle* handle) {
924  if (*handle) {
925    if (!database_.get()) {
926      NOTREACHED();
927      return;
928    }
929    database_->CancelRequest(*handle);
930  }
931  *handle = 0;
932}
933
934std::string PersonalDataManager::SaveImportedProfile(
935    const AutofillProfile& imported_profile) {
936  if (is_off_the_record_)
937    return std::string();
938
939  // Don't save a web profile if the data in the profile is a subset of an
940  // auxiliary profile.
941  for (std::vector<AutofillProfile*>::const_iterator iter =
942           auxiliary_profiles_.begin();
943       iter != auxiliary_profiles_.end(); ++iter) {
944    if (imported_profile.IsSubsetOf(**iter, app_locale_))
945      return (*iter)->guid();
946  }
947
948  std::vector<AutofillProfile> profiles;
949  std::string guid =
950      MergeProfile(imported_profile, web_profiles_.get(), app_locale_,
951                   &profiles);
952  SetProfiles(&profiles);
953  return guid;
954}
955
956
957std::string PersonalDataManager::SaveImportedCreditCard(
958    const CreditCard& imported_card) {
959  DCHECK(!imported_card.number().empty());
960  if (is_off_the_record_)
961    return std::string();
962
963  // Set to true if |imported_card| is merged into the credit card list.
964  bool merged = false;
965
966  std::string guid = imported_card.guid();
967  std::vector<CreditCard> credit_cards;
968  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
969       iter != credit_cards_.end();
970       ++iter) {
971    CreditCard* card = *iter;
972    // If |imported_card| has not yet been merged, check whether it should be
973    // with the current |card|.
974    if (!merged && card->UpdateFromImportedCard(imported_card, app_locale_)) {
975      guid = card->guid();
976      merged = true;
977    }
978
979    credit_cards.push_back(*card);
980  }
981
982  if (!merged)
983    credit_cards.push_back(imported_card);
984
985  SetCreditCards(&credit_cards);
986  return guid;
987}
988
989void PersonalDataManager::LogProfileCount() const {
990  if (!has_logged_profile_count_) {
991    metric_logger_->LogStoredProfileCount(web_profiles_.size());
992    has_logged_profile_count_ = true;
993  }
994}
995
996std::string PersonalDataManager::MostCommonCountryCodeFromProfiles() const {
997  // Count up country codes from existing profiles.
998  std::map<std::string, int> votes;
999  // TODO(estade): can we make this GetProfiles() instead? It seems to cause
1000  // errors in tests on mac trybots. See http://crbug.com/57221
1001  const std::vector<AutofillProfile*>& profiles = web_profiles();
1002  std::vector<std::string> country_codes;
1003  AutofillCountry::GetAvailableCountries(&country_codes);
1004  for (size_t i = 0; i < profiles.size(); ++i) {
1005    std::string country_code = StringToUpperASCII(UTF16ToASCII(
1006        profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY)));
1007
1008    if (std::find(country_codes.begin(), country_codes.end(), country_code) !=
1009            country_codes.end()) {
1010      // Verified profiles count 100x more than unverified ones.
1011      votes[country_code] += profiles[i]->IsVerified() ? 100 : 1;
1012    }
1013  }
1014
1015  // Take the most common country code.
1016  if (!votes.empty()) {
1017    std::map<std::string, int>::iterator iter =
1018        std::max_element(votes.begin(), votes.end(), CompareVotes);
1019    return iter->first;
1020  }
1021
1022  return std::string();
1023}
1024
1025}  // namespace autofill
1026