personal_data_manager.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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      base::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      pref_service_(NULL),
150      is_off_the_record_(false),
151      has_logged_profile_count_(false) {}
152
153void PersonalDataManager::Init(scoped_refptr<AutofillWebDataService> database,
154                               PrefService* pref_service,
155                               bool is_off_the_record) {
156  database_ = database;
157  SetPrefService(pref_service);
158  is_off_the_record_ = is_off_the_record;
159
160  if (!is_off_the_record_)
161    metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled());
162
163  // WebDataService may not be available in tests.
164  if (!database_.get())
165    return;
166
167  LoadProfiles();
168  LoadCreditCards();
169
170  database_->AddObserver(this);
171}
172
173PersonalDataManager::~PersonalDataManager() {
174  CancelPendingQuery(&pending_profiles_query_);
175  CancelPendingQuery(&pending_creditcards_query_);
176
177  if (database_.get())
178    database_->RemoveObserver(this);
179}
180
181void PersonalDataManager::OnWebDataServiceRequestDone(
182    WebDataServiceBase::Handle h,
183    const WDTypedResult* result) {
184  DCHECK(pending_profiles_query_ || pending_creditcards_query_);
185
186  if (!result) {
187    // Error from the web database.
188    if (h == pending_creditcards_query_)
189      pending_creditcards_query_ = 0;
190    else if (h == pending_profiles_query_)
191      pending_profiles_query_ = 0;
192    return;
193  }
194
195  switch (result->GetType()) {
196    case AUTOFILL_PROFILES_RESULT:
197      ReceiveLoadedProfiles(h, result);
198      break;
199    case AUTOFILL_CREDITCARDS_RESULT:
200      ReceiveLoadedCreditCards(h, result);
201      break;
202    default:
203      NOTREACHED();
204  }
205
206  // If both requests have responded, then all personal data is loaded.
207  if (pending_profiles_query_ == 0 && pending_creditcards_query_ == 0) {
208    is_data_loaded_ = true;
209    NotifyPersonalDataChanged();
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;
252    base::TrimWhitespace(field->value, base::TRIM_ALL, &value);
253
254    // If we don't know the type of the field, or the user hasn't entered any
255    // information into the field, then skip it.
256    if (!field->IsFieldFillable() || value.empty())
257      continue;
258
259    AutofillType field_type = field->Type();
260    ServerFieldType server_field_type = field_type.GetStorableType();
261    FieldTypeGroup group(field_type.group());
262
263    // There can be multiple email fields (e.g. in the case of 'confirm email'
264    // fields) but they must all contain the same value, else the profile is
265    // invalid.
266    if (server_field_type == EMAIL_ADDRESS) {
267      if (types_seen.count(server_field_type) &&
268          imported_profile->GetRawInfo(EMAIL_ADDRESS) != value) {
269        imported_profile.reset();
270        break;
271      }
272    }
273
274    // If the |field_type| and |value| don't pass basic validity checks then
275    // abandon the import.
276    if (!IsValidFieldTypeAndValue(types_seen, server_field_type, value)) {
277      imported_profile.reset();
278      local_imported_credit_card.reset();
279      break;
280    }
281
282    types_seen.insert(server_field_type);
283
284    if (group == CREDIT_CARD) {
285      if (LowerCaseEqualsASCII(field->form_control_type, "month")) {
286        DCHECK_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, server_field_type);
287        local_imported_credit_card->SetInfoForMonthInputType(value);
288      } else {
289        local_imported_credit_card->SetInfo(field_type, value, app_locale_);
290      }
291      ++importable_credit_card_fields;
292    } else {
293      // We need to store phone data in the variables, before building the whole
294      // number at the end. The rest of the fields are set "as is".
295      // If the fields are not the phone fields in question home.SetInfo() is
296      // going to return false.
297      if (!home.SetInfo(field_type, value))
298        imported_profile->SetInfo(field_type, value, app_locale_);
299
300      // Reject profiles with invalid country information.
301      if (server_field_type == ADDRESS_HOME_COUNTRY &&
302          !value.empty() &&
303          imported_profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty()) {
304        imported_profile.reset();
305        break;
306      }
307    }
308  }
309
310  // Construct the phone number. Reject the profile if the number is invalid.
311  if (imported_profile.get() && !home.IsEmpty()) {
312    base::string16 constructed_number;
313    if (!home.ParseNumber(*imported_profile, app_locale_,
314                          &constructed_number) ||
315        !imported_profile->SetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER),
316                                   constructed_number,
317                                   app_locale_)) {
318      imported_profile.reset();
319    }
320  }
321
322  // Reject the profile if minimum address and validation requirements are not
323  // met.
324  if (imported_profile.get() &&
325      !IsValidLearnableProfile(*imported_profile, app_locale_))
326    imported_profile.reset();
327
328  // Reject the credit card if we did not detect enough filled credit card
329  // fields or if the credit card number does not seem to be valid.
330  if (local_imported_credit_card.get() &&
331      !local_imported_credit_card->IsComplete()) {
332    local_imported_credit_card.reset();
333  }
334
335  // Don't import if we already have this info.
336  // Don't present an infobar if we have already saved this card number.
337  bool merged_credit_card = false;
338  if (local_imported_credit_card.get()) {
339    for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
340         iter != credit_cards_.end();
341         ++iter) {
342      // Make a local copy so that the data in |credit_cards_| isn't modified
343      // directly by the UpdateFromImportedCard() call.
344      CreditCard card = **iter;
345      if (card.UpdateFromImportedCard(*local_imported_credit_card.get(),
346                                      app_locale_)) {
347        merged_credit_card = true;
348        UpdateCreditCard(card);
349        local_imported_credit_card.reset();
350        break;
351      }
352    }
353  }
354
355  if (imported_profile.get()) {
356    // We always save imported profiles.
357    SaveImportedProfile(*imported_profile);
358  }
359  *imported_credit_card = local_imported_credit_card.Pass();
360
361  if (imported_profile.get() || *imported_credit_card || merged_credit_card)
362    return true;
363
364  FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
365                    OnInsufficientFormData());
366  return false;
367}
368
369void PersonalDataManager::AddProfile(const AutofillProfile& profile) {
370  if (is_off_the_record_)
371    return;
372
373  if (profile.IsEmpty(app_locale_))
374    return;
375
376  // Don't add an existing profile.
377  if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()))
378    return;
379
380  if (!database_.get())
381    return;
382
383  // Don't add a duplicate.
384  if (FindByContents(web_profiles_, profile))
385    return;
386
387  // Add the new profile to the web database.
388  database_->AddAutofillProfile(profile);
389
390  // Refresh our local cache and send notifications to observers.
391  Refresh();
392}
393
394void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
395  if (is_off_the_record_)
396    return;
397
398  AutofillProfile* existing_profile = GetProfileByGUID(profile.guid());
399  if (!existing_profile)
400    return;
401
402  // Don't overwrite the origin for a profile that is already stored.
403  if (existing_profile->Compare(profile) == 0)
404    return;
405
406  if (profile.IsEmpty(app_locale_)) {
407    RemoveByGUID(profile.guid());
408    return;
409  }
410
411  if (!database_.get())
412    return;
413
414  // Make the update.
415  database_->UpdateAutofillProfile(profile);
416
417  // Refresh our local cache and send notifications to observers.
418  Refresh();
419}
420
421AutofillProfile* PersonalDataManager::GetProfileByGUID(
422    const std::string& guid) {
423  const std::vector<AutofillProfile*>& profiles = GetProfiles();
424  std::vector<AutofillProfile*>::const_iterator iter =
425      FindElementByGUID<AutofillProfile>(profiles, guid);
426  return (iter != profiles.end()) ? *iter : NULL;
427}
428
429void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) {
430  if (is_off_the_record_)
431    return;
432
433  if (credit_card.IsEmpty(app_locale_))
434    return;
435
436  if (FindByGUID<CreditCard>(credit_cards_, credit_card.guid()))
437    return;
438
439  if (!database_.get())
440    return;
441
442  // Don't add a duplicate.
443  if (FindByContents(credit_cards_, credit_card))
444    return;
445
446  // Add the new credit card to the web database.
447  database_->AddCreditCard(credit_card);
448
449  // Refresh our local cache and send notifications to observers.
450  Refresh();
451}
452
453void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
454  if (is_off_the_record_)
455    return;
456
457  CreditCard* existing_credit_card = GetCreditCardByGUID(credit_card.guid());
458  if (!existing_credit_card)
459    return;
460
461  // Don't overwrite the origin for a credit card that is already stored.
462  if (existing_credit_card->Compare(credit_card) == 0)
463    return;
464
465  if (credit_card.IsEmpty(app_locale_)) {
466    RemoveByGUID(credit_card.guid());
467    return;
468  }
469
470  if (!database_.get())
471    return;
472
473  // Make the update.
474  database_->UpdateCreditCard(credit_card);
475
476  // Refresh our local cache and send notifications to observers.
477  Refresh();
478}
479
480void PersonalDataManager::RemoveByGUID(const std::string& guid) {
481  if (is_off_the_record_)
482    return;
483
484  bool is_credit_card = FindByGUID<CreditCard>(credit_cards_, guid);
485  bool is_profile = !is_credit_card &&
486      FindByGUID<AutofillProfile>(web_profiles_, guid);
487  if (!is_credit_card && !is_profile)
488    return;
489
490  if (!database_.get())
491    return;
492
493  if (is_credit_card)
494    database_->RemoveCreditCard(guid);
495  else
496    database_->RemoveAutofillProfile(guid);
497
498  // Refresh our local cache and send notifications to observers.
499  Refresh();
500}
501
502CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) {
503  const std::vector<CreditCard*>& credit_cards = GetCreditCards();
504  std::vector<CreditCard*>::const_iterator iter =
505      FindElementByGUID<CreditCard>(credit_cards, guid);
506  return (iter != credit_cards.end()) ? *iter : NULL;
507}
508
509void PersonalDataManager::GetNonEmptyTypes(
510    ServerFieldTypeSet* non_empty_types) {
511  const std::vector<AutofillProfile*>& profiles = GetProfiles();
512  for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
513       iter != profiles.end(); ++iter) {
514    (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
515  }
516
517  for (ScopedVector<CreditCard>::const_iterator iter = credit_cards_.begin();
518       iter != credit_cards_.end(); ++iter) {
519    (*iter)->GetNonEmptyTypes(app_locale_, non_empty_types);
520  }
521}
522
523bool PersonalDataManager::IsDataLoaded() const {
524  return is_data_loaded_;
525}
526
527const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const {
528  if (!pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled)) {
529    return web_profiles();
530  }
531
532  profiles_.clear();
533
534  // Populates |auxiliary_profiles_|.
535  LoadAuxiliaryProfiles();
536
537  profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end());
538  profiles_.insert(profiles_.end(),
539      auxiliary_profiles_.begin(), auxiliary_profiles_.end());
540  return profiles_;
541}
542
543const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const {
544  return web_profiles_.get();
545}
546
547const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
548  return credit_cards_.get();
549}
550
551void PersonalDataManager::Refresh() {
552  LoadProfiles();
553  LoadCreditCards();
554}
555
556void PersonalDataManager::GetProfileSuggestions(
557    const AutofillType& type,
558    const base::string16& field_contents,
559    bool field_is_autofilled,
560    const std::vector<ServerFieldType>& other_field_types,
561    const base::Callback<bool(const AutofillProfile&)>& filter,
562    std::vector<base::string16>* values,
563    std::vector<base::string16>* labels,
564    std::vector<base::string16>* icons,
565    std::vector<GUIDPair>* guid_pairs) {
566  values->clear();
567  labels->clear();
568  icons->clear();
569  guid_pairs->clear();
570
571  const std::vector<AutofillProfile*>& profiles = GetProfiles();
572  std::vector<AutofillProfile*> matched_profiles;
573  for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
574       iter != profiles.end(); ++iter) {
575    AutofillProfile* profile = *iter;
576
577    // The value of the stored data for this field type in the |profile|.
578    std::vector<base::string16> multi_values;
579    profile->GetMultiInfo(type, app_locale_, &multi_values);
580
581    for (size_t i = 0; i < multi_values.size(); ++i) {
582      if (!field_is_autofilled) {
583        // Suggest data that starts with what the user has typed.
584        if (!multi_values[i].empty() &&
585            StartsWith(multi_values[i], field_contents, false) &&
586            (filter.is_null() || filter.Run(*profile))) {
587          matched_profiles.push_back(profile);
588          values->push_back(multi_values[i]);
589          guid_pairs->push_back(GUIDPair(profile->guid(), i));
590        }
591      } else {
592        if (multi_values[i].empty())
593          continue;
594
595        base::string16 profile_value_lower_case(
596            StringToLowerASCII(multi_values[i]));
597        base::string16 field_value_lower_case(
598            StringToLowerASCII(field_contents));
599        // Phone numbers could be split in US forms, so field value could be
600        // either prefix or suffix of the phone.
601        bool matched_phones = false;
602        if (type.GetStorableType() == PHONE_HOME_NUMBER &&
603            !field_value_lower_case.empty() &&
604            profile_value_lower_case.find(field_value_lower_case) !=
605                base::string16::npos) {
606          matched_phones = true;
607        }
608
609        // Suggest variants of the profile that's already been filled in.
610        if (matched_phones ||
611            profile_value_lower_case == field_value_lower_case) {
612          for (size_t j = 0; j < multi_values.size(); ++j) {
613            if (!multi_values[j].empty()) {
614              values->push_back(multi_values[j]);
615              guid_pairs->push_back(GUIDPair(profile->guid(), j));
616            }
617          }
618
619          // We've added all the values for this profile so move on to the
620          // next.
621          break;
622        }
623      }
624    }
625  }
626
627  if (!field_is_autofilled) {
628    AutofillProfile::CreateInferredLabels(
629        matched_profiles, &other_field_types,
630        type.GetStorableType(), 1, labels);
631  } else {
632    // No sub-labels for previously filled fields.
633    labels->resize(values->size());
634  }
635
636  // No icons for profile suggestions.
637  icons->resize(values->size());
638}
639
640void PersonalDataManager::GetCreditCardSuggestions(
641    const AutofillType& type,
642    const base::string16& field_contents,
643    std::vector<base::string16>* values,
644    std::vector<base::string16>* labels,
645    std::vector<base::string16>* icons,
646    std::vector<GUIDPair>* guid_pairs) {
647  values->clear();
648  labels->clear();
649  icons->clear();
650  guid_pairs->clear();
651
652  const std::vector<CreditCard*>& credit_cards = GetCreditCards();
653  for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
654       iter != credit_cards.end(); ++iter) {
655    CreditCard* credit_card = *iter;
656
657    // The value of the stored data for this field type in the |credit_card|.
658    base::string16 creditcard_field_value =
659        credit_card->GetInfo(type, app_locale_);
660    if (!creditcard_field_value.empty() &&
661        StartsWith(creditcard_field_value, field_contents, false)) {
662      if (type.GetStorableType() == CREDIT_CARD_NUMBER)
663        creditcard_field_value = credit_card->ObfuscatedNumber();
664
665      base::string16 label;
666      if (credit_card->number().empty()) {
667        // If there is no CC number, return name to show something.
668        label =
669            credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_);
670      } else {
671        label = kCreditCardPrefix;
672        label.append(credit_card->LastFourDigits());
673      }
674
675      values->push_back(creditcard_field_value);
676      labels->push_back(label);
677      icons->push_back(base::UTF8ToUTF16(credit_card->type()));
678      guid_pairs->push_back(GUIDPair(credit_card->guid(), 0));
679    }
680  }
681}
682
683bool PersonalDataManager::IsAutofillEnabled() const {
684  DCHECK(pref_service_);
685  return pref_service_->GetBoolean(prefs::kAutofillEnabled);
686}
687
688std::string PersonalDataManager::CountryCodeForCurrentTimezone() const {
689  return base::CountryCodeForCurrentTimezone();
690}
691
692void PersonalDataManager::SetPrefService(PrefService* pref_service) {
693  enabled_pref_.reset(new BooleanPrefMember);
694  pref_service_ = pref_service;
695  // |pref_service_| can be NULL in tests.
696  if (pref_service_) {
697    enabled_pref_->Init(prefs::kAutofillEnabled, pref_service_,
698        base::Bind(&PersonalDataManager::EnabledPrefChanged,
699                   base::Unretained(this)));
700  }
701}
702
703// static
704bool PersonalDataManager::IsValidLearnableProfile(
705    const AutofillProfile& profile,
706    const std::string& app_locale) {
707  if (!IsMinimumAddress(profile, app_locale))
708    return false;
709
710  base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS);
711  if (!email.empty() && !IsValidEmailAddress(email))
712    return false;
713
714  // Reject profiles with invalid US state information.
715  if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE))
716    return false;
717
718  // Reject profiles with invalid US zip information.
719  if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP))
720    return false;
721
722  return true;
723}
724
725// static
726std::string PersonalDataManager::MergeProfile(
727    const AutofillProfile& new_profile,
728    const std::vector<AutofillProfile*>& existing_profiles,
729    const std::string& app_locale,
730    std::vector<AutofillProfile>* merged_profiles) {
731  merged_profiles->clear();
732
733  // Set to true if |existing_profiles| already contains an equivalent profile.
734  bool matching_profile_found = false;
735  std::string guid = new_profile.guid();
736
737  // If we have already saved this address, merge in any missing values.
738  // Only merge with the first match.
739  for (std::vector<AutofillProfile*>::const_iterator iter =
740           existing_profiles.begin();
741       iter != existing_profiles.end(); ++iter) {
742    AutofillProfile* existing_profile = *iter;
743    if (!matching_profile_found &&
744        !new_profile.PrimaryValue().empty() &&
745        StringToLowerASCII(existing_profile->PrimaryValue()) ==
746            StringToLowerASCII(new_profile.PrimaryValue())) {
747      // Unverified profiles should always be updated with the newer data,
748      // whereas verified profiles should only ever be overwritten by verified
749      // data.  If an automatically aggregated profile would overwrite a
750      // verified profile, just drop it.
751      matching_profile_found = true;
752      guid = existing_profile->guid();
753      if (!existing_profile->IsVerified() || new_profile.IsVerified())
754        existing_profile->OverwriteWithOrAddTo(new_profile, app_locale);
755    }
756    merged_profiles->push_back(*existing_profile);
757  }
758
759  // If the new profile was not merged with an existing one, add it to the list.
760  if (!matching_profile_found)
761    merged_profiles->push_back(new_profile);
762
763  return guid;
764}
765
766bool PersonalDataManager::IsCountryOfInterest(const std::string& country_code)
767    const {
768  DCHECK_EQ(2U, country_code.size());
769
770  const std::vector<AutofillProfile*>& profiles = web_profiles();
771  std::list<std::string> country_codes;
772  for (size_t i = 0; i < profiles.size(); ++i) {
773    country_codes.push_back(StringToLowerASCII(base::UTF16ToASCII(
774        profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY))));
775  }
776
777  std::string timezone_country = CountryCodeForCurrentTimezone();
778  if (!timezone_country.empty())
779    country_codes.push_back(StringToLowerASCII(timezone_country));
780
781  // Only take the locale into consideration if all else fails.
782  if (country_codes.empty()) {
783    country_codes.push_back(StringToLowerASCII(
784        AutofillCountry::CountryCodeForLocale(app_locale())));
785  }
786
787  return std::find(country_codes.begin(), country_codes.end(),
788                   StringToLowerASCII(country_code)) != country_codes.end();
789}
790
791const std::string& PersonalDataManager::GetDefaultCountryCodeForNewAddress()
792    const {
793  if (default_country_code_.empty())
794    default_country_code_ = MostCommonCountryCodeFromProfiles();
795
796  // Failing that, guess based on system timezone.
797  if (default_country_code_.empty())
798    default_country_code_ = CountryCodeForCurrentTimezone();
799
800  // Failing that, guess based on locale.
801  if (default_country_code_.empty())
802    default_country_code_ = AutofillCountry::CountryCodeForLocale(app_locale());
803
804  return default_country_code_;
805}
806
807void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
808  if (is_off_the_record_)
809    return;
810
811  // Remove empty profiles from input.
812  profiles->erase(std::remove_if(profiles->begin(), profiles->end(),
813                                 IsEmptyFunctor<AutofillProfile>(app_locale_)),
814                  profiles->end());
815
816  if (!database_.get())
817    return;
818
819  // Any profiles that are not in the new profile list should be removed from
820  // the web database.
821  for (std::vector<AutofillProfile*>::const_iterator iter =
822           web_profiles_.begin();
823       iter != web_profiles_.end(); ++iter) {
824    if (!FindByGUID<AutofillProfile>(*profiles, (*iter)->guid()))
825      database_->RemoveAutofillProfile((*iter)->guid());
826  }
827
828  // Update the web database with the existing profiles.
829  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
830       iter != profiles->end(); ++iter) {
831    if (FindByGUID<AutofillProfile>(web_profiles_, iter->guid()))
832      database_->UpdateAutofillProfile(*iter);
833  }
834
835  // Add the new profiles to the web database.  Don't add a duplicate.
836  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
837       iter != profiles->end(); ++iter) {
838    if (!FindByGUID<AutofillProfile>(web_profiles_, iter->guid()) &&
839        !FindByContents(web_profiles_, *iter))
840      database_->AddAutofillProfile(*iter);
841  }
842
843  // Copy in the new profiles.
844  web_profiles_.clear();
845  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
846       iter != profiles->end(); ++iter) {
847    web_profiles_.push_back(new AutofillProfile(*iter));
848  }
849
850  // Refresh our local cache and send notifications to observers.
851  Refresh();
852}
853
854void PersonalDataManager::SetCreditCards(
855    std::vector<CreditCard>* credit_cards) {
856  if (is_off_the_record_)
857    return;
858
859  // Remove empty credit cards from input.
860  credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(),
861                                     IsEmptyFunctor<CreditCard>(app_locale_)),
862                      credit_cards->end());
863
864  if (!database_.get())
865    return;
866
867  // Any credit cards that are not in the new credit card list should be
868  // removed.
869  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
870       iter != credit_cards_.end(); ++iter) {
871    if (!FindByGUID<CreditCard>(*credit_cards, (*iter)->guid()))
872      database_->RemoveCreditCard((*iter)->guid());
873  }
874
875  // Update the web database with the existing credit cards.
876  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
877       iter != credit_cards->end(); ++iter) {
878    if (FindByGUID<CreditCard>(credit_cards_, iter->guid()))
879      database_->UpdateCreditCard(*iter);
880  }
881
882  // Add the new credit cards to the web database.  Don't add a duplicate.
883  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
884       iter != credit_cards->end(); ++iter) {
885    if (!FindByGUID<CreditCard>(credit_cards_, iter->guid()) &&
886        !FindByContents(credit_cards_, *iter))
887      database_->AddCreditCard(*iter);
888  }
889
890  // Copy in the new credit cards.
891  credit_cards_.clear();
892  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
893       iter != credit_cards->end(); ++iter) {
894    credit_cards_.push_back(new CreditCard(*iter));
895  }
896
897  // Refresh our local cache and send notifications to observers.
898  Refresh();
899}
900
901void PersonalDataManager::LoadProfiles() {
902  if (!database_.get()) {
903    NOTREACHED();
904    return;
905  }
906
907  CancelPendingQuery(&pending_profiles_query_);
908
909  pending_profiles_query_ = database_->GetAutofillProfiles(this);
910}
911
912// Win, Linux, and iOS implementations do nothing. Mac and Android
913// implementations fill in the contents of |auxiliary_profiles_|.
914#if defined(OS_IOS) || (!defined(OS_MACOSX) && !defined(OS_ANDROID))
915void PersonalDataManager::LoadAuxiliaryProfiles() const {
916}
917#endif
918
919void PersonalDataManager::LoadCreditCards() {
920  if (!database_.get()) {
921    NOTREACHED();
922    return;
923  }
924
925  CancelPendingQuery(&pending_creditcards_query_);
926
927  pending_creditcards_query_ = database_->GetCreditCards(this);
928}
929
930void PersonalDataManager::ReceiveLoadedProfiles(WebDataServiceBase::Handle h,
931                                                const WDTypedResult* result) {
932  DCHECK_EQ(pending_profiles_query_, h);
933
934  pending_profiles_query_ = 0;
935  web_profiles_.clear();
936
937  const WDResult<std::vector<AutofillProfile*> >* r =
938      static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result);
939
940  std::vector<AutofillProfile*> profiles = r->GetValue();
941  for (std::vector<AutofillProfile*>::iterator iter = profiles.begin();
942       iter != profiles.end(); ++iter) {
943    web_profiles_.push_back(*iter);
944  }
945
946  LogProfileCount();
947}
948
949void PersonalDataManager::ReceiveLoadedCreditCards(
950    WebDataServiceBase::Handle h, const WDTypedResult* result) {
951  DCHECK_EQ(pending_creditcards_query_, h);
952
953  pending_creditcards_query_ = 0;
954  credit_cards_.clear();
955
956  const WDResult<std::vector<CreditCard*> >* r =
957      static_cast<const WDResult<std::vector<CreditCard*> >*>(result);
958
959  std::vector<CreditCard*> credit_cards = r->GetValue();
960  for (std::vector<CreditCard*>::iterator iter = credit_cards.begin();
961       iter != credit_cards.end(); ++iter) {
962    credit_cards_.push_back(*iter);
963  }
964}
965
966void PersonalDataManager::CancelPendingQuery(
967    WebDataServiceBase::Handle* handle) {
968  if (*handle) {
969    if (!database_.get()) {
970      NOTREACHED();
971      return;
972    }
973    database_->CancelRequest(*handle);
974  }
975  *handle = 0;
976}
977
978std::string PersonalDataManager::SaveImportedProfile(
979    const AutofillProfile& imported_profile) {
980  if (is_off_the_record_)
981    return std::string();
982
983  // Don't save a web profile if the data in the profile is a subset of an
984  // auxiliary profile.
985  for (std::vector<AutofillProfile*>::const_iterator iter =
986           auxiliary_profiles_.begin();
987       iter != auxiliary_profiles_.end(); ++iter) {
988    if (imported_profile.IsSubsetOf(**iter, app_locale_))
989      return (*iter)->guid();
990  }
991
992  std::vector<AutofillProfile> profiles;
993  std::string guid =
994      MergeProfile(imported_profile, web_profiles_.get(), app_locale_,
995                   &profiles);
996  SetProfiles(&profiles);
997  return guid;
998}
999
1000void PersonalDataManager::NotifyPersonalDataChanged() {
1001  FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
1002                    OnPersonalDataChanged());
1003}
1004
1005std::string PersonalDataManager::SaveImportedCreditCard(
1006    const CreditCard& imported_card) {
1007  DCHECK(!imported_card.number().empty());
1008  if (is_off_the_record_)
1009    return std::string();
1010
1011  // Set to true if |imported_card| is merged into the credit card list.
1012  bool merged = false;
1013
1014  std::string guid = imported_card.guid();
1015  std::vector<CreditCard> credit_cards;
1016  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
1017       iter != credit_cards_.end();
1018       ++iter) {
1019    CreditCard* card = *iter;
1020    // If |imported_card| has not yet been merged, check whether it should be
1021    // with the current |card|.
1022    if (!merged && card->UpdateFromImportedCard(imported_card, app_locale_)) {
1023      guid = card->guid();
1024      merged = true;
1025    }
1026
1027    credit_cards.push_back(*card);
1028  }
1029
1030  if (!merged)
1031    credit_cards.push_back(imported_card);
1032
1033  SetCreditCards(&credit_cards);
1034  return guid;
1035}
1036
1037void PersonalDataManager::LogProfileCount() const {
1038  if (!has_logged_profile_count_) {
1039    metric_logger_->LogStoredProfileCount(web_profiles_.size());
1040    has_logged_profile_count_ = true;
1041  }
1042}
1043
1044std::string PersonalDataManager::MostCommonCountryCodeFromProfiles() const {
1045  if (!IsAutofillEnabled())
1046    return std::string();
1047
1048  // Count up country codes from existing profiles.
1049  std::map<std::string, int> votes;
1050  // TODO(estade): can we make this GetProfiles() instead? It seems to cause
1051  // errors in tests on mac trybots. See http://crbug.com/57221
1052  const std::vector<AutofillProfile*>& profiles = web_profiles();
1053  std::vector<std::string> country_codes;
1054  AutofillCountry::GetAvailableCountries(&country_codes);
1055  for (size_t i = 0; i < profiles.size(); ++i) {
1056    std::string country_code = StringToUpperASCII(base::UTF16ToASCII(
1057        profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY)));
1058
1059    if (std::find(country_codes.begin(), country_codes.end(), country_code) !=
1060            country_codes.end()) {
1061      // Verified profiles count 100x more than unverified ones.
1062      votes[country_code] += profiles[i]->IsVerified() ? 100 : 1;
1063    }
1064  }
1065
1066  // Take the most common country code.
1067  if (!votes.empty()) {
1068    std::map<std::string, int>::iterator iter =
1069        std::max_element(votes.begin(), votes.end(), CompareVotes);
1070    return iter->first;
1071  }
1072
1073  return std::string();
1074}
1075
1076void PersonalDataManager::EnabledPrefChanged() {
1077  default_country_code_.clear();
1078  NotifyPersonalDataChanged();
1079}
1080
1081}  // namespace autofill
1082