personal_data_manager.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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->EqualsSansOrigin(profile))
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 defined(OS_MACOSX) && !defined(OS_IOS)
529  if (!pref_service_->GetBoolean(prefs::kAutofillUseMacAddressBook))
530    return web_profiles();
531#else
532  if (!pref_service_->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled))
533    return web_profiles();
534#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
535
536  profiles_.clear();
537
538  // Populates |auxiliary_profiles_|.
539  LoadAuxiliaryProfiles();
540
541  profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end());
542  profiles_.insert(profiles_.end(),
543      auxiliary_profiles_.begin(), auxiliary_profiles_.end());
544  return profiles_;
545}
546
547const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const {
548  return web_profiles_.get();
549}
550
551const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
552  return credit_cards_.get();
553}
554
555void PersonalDataManager::Refresh() {
556  LoadProfiles();
557  LoadCreditCards();
558}
559
560void PersonalDataManager::GetProfileSuggestions(
561    const AutofillType& type,
562    const base::string16& field_contents,
563    bool field_is_autofilled,
564    const std::vector<ServerFieldType>& other_field_types,
565    const base::Callback<bool(const AutofillProfile&)>& filter,
566    std::vector<base::string16>* values,
567    std::vector<base::string16>* labels,
568    std::vector<base::string16>* icons,
569    std::vector<GUIDPair>* guid_pairs) {
570  values->clear();
571  labels->clear();
572  icons->clear();
573  guid_pairs->clear();
574
575  const std::vector<AutofillProfile*>& profiles = GetProfiles();
576  std::vector<AutofillProfile*> matched_profiles;
577  for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
578       iter != profiles.end(); ++iter) {
579    AutofillProfile* profile = *iter;
580
581    // The value of the stored data for this field type in the |profile|.
582    std::vector<base::string16> multi_values;
583    profile->GetMultiInfo(type, app_locale_, &multi_values);
584
585    for (size_t i = 0; i < multi_values.size(); ++i) {
586      if (!field_is_autofilled) {
587        // Suggest data that starts with what the user has typed.
588        if (!multi_values[i].empty() &&
589            StartsWith(multi_values[i], field_contents, false) &&
590            (filter.is_null() || filter.Run(*profile))) {
591          matched_profiles.push_back(profile);
592          values->push_back(multi_values[i]);
593          guid_pairs->push_back(GUIDPair(profile->guid(), i));
594        }
595      } else {
596        if (multi_values[i].empty())
597          continue;
598
599        base::string16 profile_value_lower_case(
600            StringToLowerASCII(multi_values[i]));
601        base::string16 field_value_lower_case(
602            StringToLowerASCII(field_contents));
603        // Phone numbers could be split in US forms, so field value could be
604        // either prefix or suffix of the phone.
605        bool matched_phones = false;
606        if (type.GetStorableType() == PHONE_HOME_NUMBER &&
607            !field_value_lower_case.empty() &&
608            profile_value_lower_case.find(field_value_lower_case) !=
609                base::string16::npos) {
610          matched_phones = true;
611        }
612
613        // Suggest variants of the profile that's already been filled in.
614        if (matched_phones ||
615            profile_value_lower_case == field_value_lower_case) {
616          for (size_t j = 0; j < multi_values.size(); ++j) {
617            if (!multi_values[j].empty()) {
618              values->push_back(multi_values[j]);
619              guid_pairs->push_back(GUIDPair(profile->guid(), j));
620            }
621          }
622
623          // We've added all the values for this profile so move on to the
624          // next.
625          break;
626        }
627      }
628    }
629  }
630
631  if (!field_is_autofilled) {
632    AutofillProfile::CreateInferredLabels(
633        matched_profiles, &other_field_types,
634        type.GetStorableType(), 1, labels);
635  } else {
636    // No sub-labels for previously filled fields.
637    labels->resize(values->size());
638  }
639
640  // No icons for profile suggestions.
641  icons->resize(values->size());
642}
643
644void PersonalDataManager::GetCreditCardSuggestions(
645    const AutofillType& type,
646    const base::string16& field_contents,
647    std::vector<base::string16>* values,
648    std::vector<base::string16>* labels,
649    std::vector<base::string16>* icons,
650    std::vector<GUIDPair>* guid_pairs) {
651  values->clear();
652  labels->clear();
653  icons->clear();
654  guid_pairs->clear();
655
656  const std::vector<CreditCard*>& credit_cards = GetCreditCards();
657  for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
658       iter != credit_cards.end(); ++iter) {
659    CreditCard* credit_card = *iter;
660
661    // The value of the stored data for this field type in the |credit_card|.
662    base::string16 creditcard_field_value =
663        credit_card->GetInfo(type, app_locale_);
664    if (!creditcard_field_value.empty() &&
665        StartsWith(creditcard_field_value, field_contents, false)) {
666      if (type.GetStorableType() == CREDIT_CARD_NUMBER)
667        creditcard_field_value = credit_card->ObfuscatedNumber();
668
669      base::string16 label;
670      if (credit_card->number().empty()) {
671        // If there is no CC number, return name to show something.
672        label =
673            credit_card->GetInfo(AutofillType(CREDIT_CARD_NAME), app_locale_);
674      } else {
675        label = kCreditCardPrefix;
676        label.append(credit_card->LastFourDigits());
677      }
678
679      values->push_back(creditcard_field_value);
680      labels->push_back(label);
681      icons->push_back(base::UTF8ToUTF16(credit_card->type()));
682      guid_pairs->push_back(GUIDPair(credit_card->guid(), 0));
683    }
684  }
685}
686
687bool PersonalDataManager::IsAutofillEnabled() const {
688  DCHECK(pref_service_);
689  return pref_service_->GetBoolean(prefs::kAutofillEnabled);
690}
691
692std::string PersonalDataManager::CountryCodeForCurrentTimezone() const {
693  return base::CountryCodeForCurrentTimezone();
694}
695
696void PersonalDataManager::SetPrefService(PrefService* pref_service) {
697  enabled_pref_.reset(new BooleanPrefMember);
698  pref_service_ = pref_service;
699  // |pref_service_| can be NULL in tests.
700  if (pref_service_) {
701    enabled_pref_->Init(prefs::kAutofillEnabled, pref_service_,
702        base::Bind(&PersonalDataManager::EnabledPrefChanged,
703                   base::Unretained(this)));
704  }
705}
706
707// static
708bool PersonalDataManager::IsValidLearnableProfile(
709    const AutofillProfile& profile,
710    const std::string& app_locale) {
711  if (!IsMinimumAddress(profile, app_locale))
712    return false;
713
714  base::string16 email = profile.GetRawInfo(EMAIL_ADDRESS);
715  if (!email.empty() && !IsValidEmailAddress(email))
716    return false;
717
718  // Reject profiles with invalid US state information.
719  if (profile.IsPresentButInvalid(ADDRESS_HOME_STATE))
720    return false;
721
722  // Reject profiles with invalid US zip information.
723  if (profile.IsPresentButInvalid(ADDRESS_HOME_ZIP))
724    return false;
725
726  return true;
727}
728
729// static
730std::string PersonalDataManager::MergeProfile(
731    const AutofillProfile& new_profile,
732    const std::vector<AutofillProfile*>& existing_profiles,
733    const std::string& app_locale,
734    std::vector<AutofillProfile>* merged_profiles) {
735  merged_profiles->clear();
736
737  // Set to true if |existing_profiles| already contains an equivalent profile.
738  bool matching_profile_found = false;
739  std::string guid = new_profile.guid();
740
741  // If we have already saved this address, merge in any missing values.
742  // Only merge with the first match.
743  for (std::vector<AutofillProfile*>::const_iterator iter =
744           existing_profiles.begin();
745       iter != existing_profiles.end(); ++iter) {
746    AutofillProfile* existing_profile = *iter;
747    if (!matching_profile_found &&
748        !new_profile.PrimaryValue().empty() &&
749        StringToLowerASCII(existing_profile->PrimaryValue()) ==
750            StringToLowerASCII(new_profile.PrimaryValue())) {
751      // Unverified profiles should always be updated with the newer data,
752      // whereas verified profiles should only ever be overwritten by verified
753      // data.  If an automatically aggregated profile would overwrite a
754      // verified profile, just drop it.
755      matching_profile_found = true;
756      guid = existing_profile->guid();
757      if (!existing_profile->IsVerified() || new_profile.IsVerified())
758        existing_profile->OverwriteWithOrAddTo(new_profile, app_locale);
759    }
760    merged_profiles->push_back(*existing_profile);
761  }
762
763  // If the new profile was not merged with an existing one, add it to the list.
764  if (!matching_profile_found)
765    merged_profiles->push_back(new_profile);
766
767  return guid;
768}
769
770bool PersonalDataManager::IsCountryOfInterest(const std::string& country_code)
771    const {
772  DCHECK_EQ(2U, country_code.size());
773
774  const std::vector<AutofillProfile*>& profiles = web_profiles();
775  std::list<std::string> country_codes;
776  for (size_t i = 0; i < profiles.size(); ++i) {
777    country_codes.push_back(StringToLowerASCII(base::UTF16ToASCII(
778        profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY))));
779  }
780
781  std::string timezone_country = CountryCodeForCurrentTimezone();
782  if (!timezone_country.empty())
783    country_codes.push_back(StringToLowerASCII(timezone_country));
784
785  // Only take the locale into consideration if all else fails.
786  if (country_codes.empty()) {
787    country_codes.push_back(StringToLowerASCII(
788        AutofillCountry::CountryCodeForLocale(app_locale())));
789  }
790
791  return std::find(country_codes.begin(), country_codes.end(),
792                   StringToLowerASCII(country_code)) != country_codes.end();
793}
794
795const std::string& PersonalDataManager::GetDefaultCountryCodeForNewAddress()
796    const {
797  if (default_country_code_.empty())
798    default_country_code_ = MostCommonCountryCodeFromProfiles();
799
800  // Failing that, guess based on system timezone.
801  if (default_country_code_.empty())
802    default_country_code_ = CountryCodeForCurrentTimezone();
803
804  // Failing that, guess based on locale.
805  if (default_country_code_.empty())
806    default_country_code_ = AutofillCountry::CountryCodeForLocale(app_locale());
807
808  return default_country_code_;
809}
810
811void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
812  if (is_off_the_record_)
813    return;
814
815  // Remove empty profiles from input.
816  profiles->erase(std::remove_if(profiles->begin(), profiles->end(),
817                                 IsEmptyFunctor<AutofillProfile>(app_locale_)),
818                  profiles->end());
819
820  if (!database_.get())
821    return;
822
823  // Any profiles that are not in the new profile list should be removed from
824  // the web database.
825  for (std::vector<AutofillProfile*>::const_iterator iter =
826           web_profiles_.begin();
827       iter != web_profiles_.end(); ++iter) {
828    if (!FindByGUID<AutofillProfile>(*profiles, (*iter)->guid()))
829      database_->RemoveAutofillProfile((*iter)->guid());
830  }
831
832  // Update the web database with the existing profiles.
833  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
834       iter != profiles->end(); ++iter) {
835    if (FindByGUID<AutofillProfile>(web_profiles_, iter->guid()))
836      database_->UpdateAutofillProfile(*iter);
837  }
838
839  // Add the new profiles to the web database.  Don't add a duplicate.
840  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
841       iter != profiles->end(); ++iter) {
842    if (!FindByGUID<AutofillProfile>(web_profiles_, iter->guid()) &&
843        !FindByContents(web_profiles_, *iter))
844      database_->AddAutofillProfile(*iter);
845  }
846
847  // Copy in the new profiles.
848  web_profiles_.clear();
849  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
850       iter != profiles->end(); ++iter) {
851    web_profiles_.push_back(new AutofillProfile(*iter));
852  }
853
854  // Refresh our local cache and send notifications to observers.
855  Refresh();
856}
857
858void PersonalDataManager::SetCreditCards(
859    std::vector<CreditCard>* credit_cards) {
860  if (is_off_the_record_)
861    return;
862
863  // Remove empty credit cards from input.
864  credit_cards->erase(std::remove_if(credit_cards->begin(), credit_cards->end(),
865                                     IsEmptyFunctor<CreditCard>(app_locale_)),
866                      credit_cards->end());
867
868  if (!database_.get())
869    return;
870
871  // Any credit cards that are not in the new credit card list should be
872  // removed.
873  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
874       iter != credit_cards_.end(); ++iter) {
875    if (!FindByGUID<CreditCard>(*credit_cards, (*iter)->guid()))
876      database_->RemoveCreditCard((*iter)->guid());
877  }
878
879  // Update the web database with the existing credit cards.
880  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
881       iter != credit_cards->end(); ++iter) {
882    if (FindByGUID<CreditCard>(credit_cards_, iter->guid()))
883      database_->UpdateCreditCard(*iter);
884  }
885
886  // Add the new credit cards to the web database.  Don't add a duplicate.
887  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
888       iter != credit_cards->end(); ++iter) {
889    if (!FindByGUID<CreditCard>(credit_cards_, iter->guid()) &&
890        !FindByContents(credit_cards_, *iter))
891      database_->AddCreditCard(*iter);
892  }
893
894  // Copy in the new credit cards.
895  credit_cards_.clear();
896  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
897       iter != credit_cards->end(); ++iter) {
898    credit_cards_.push_back(new CreditCard(*iter));
899  }
900
901  // Refresh our local cache and send notifications to observers.
902  Refresh();
903}
904
905void PersonalDataManager::LoadProfiles() {
906  if (!database_.get()) {
907    NOTREACHED();
908    return;
909  }
910
911  CancelPendingQuery(&pending_profiles_query_);
912
913  pending_profiles_query_ = database_->GetAutofillProfiles(this);
914}
915
916// Win, Linux, and iOS implementations do nothing. Mac and Android
917// implementations fill in the contents of |auxiliary_profiles_|.
918#if defined(OS_IOS) || (!defined(OS_MACOSX) && !defined(OS_ANDROID))
919void PersonalDataManager::LoadAuxiliaryProfiles() const {
920}
921#endif
922
923void PersonalDataManager::LoadCreditCards() {
924  if (!database_.get()) {
925    NOTREACHED();
926    return;
927  }
928
929  CancelPendingQuery(&pending_creditcards_query_);
930
931  pending_creditcards_query_ = database_->GetCreditCards(this);
932}
933
934void PersonalDataManager::ReceiveLoadedProfiles(WebDataServiceBase::Handle h,
935                                                const WDTypedResult* result) {
936  DCHECK_EQ(pending_profiles_query_, h);
937
938  pending_profiles_query_ = 0;
939  web_profiles_.clear();
940
941  const WDResult<std::vector<AutofillProfile*> >* r =
942      static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result);
943
944  std::vector<AutofillProfile*> profiles = r->GetValue();
945  for (std::vector<AutofillProfile*>::iterator iter = profiles.begin();
946       iter != profiles.end(); ++iter) {
947    web_profiles_.push_back(*iter);
948  }
949
950  LogProfileCount();
951}
952
953void PersonalDataManager::ReceiveLoadedCreditCards(
954    WebDataServiceBase::Handle h, const WDTypedResult* result) {
955  DCHECK_EQ(pending_creditcards_query_, h);
956
957  pending_creditcards_query_ = 0;
958  credit_cards_.clear();
959
960  const WDResult<std::vector<CreditCard*> >* r =
961      static_cast<const WDResult<std::vector<CreditCard*> >*>(result);
962
963  std::vector<CreditCard*> credit_cards = r->GetValue();
964  for (std::vector<CreditCard*>::iterator iter = credit_cards.begin();
965       iter != credit_cards.end(); ++iter) {
966    credit_cards_.push_back(*iter);
967  }
968}
969
970void PersonalDataManager::CancelPendingQuery(
971    WebDataServiceBase::Handle* handle) {
972  if (*handle) {
973    if (!database_.get()) {
974      NOTREACHED();
975      return;
976    }
977    database_->CancelRequest(*handle);
978  }
979  *handle = 0;
980}
981
982std::string PersonalDataManager::SaveImportedProfile(
983    const AutofillProfile& imported_profile) {
984  if (is_off_the_record_)
985    return std::string();
986
987  // Don't save a web profile if the data in the profile is a subset of an
988  // auxiliary profile.
989  for (std::vector<AutofillProfile*>::const_iterator iter =
990           auxiliary_profiles_.begin();
991       iter != auxiliary_profiles_.end(); ++iter) {
992    if (imported_profile.IsSubsetOf(**iter, app_locale_))
993      return (*iter)->guid();
994  }
995
996  std::vector<AutofillProfile> profiles;
997  std::string guid =
998      MergeProfile(imported_profile, web_profiles_.get(), app_locale_,
999                   &profiles);
1000  SetProfiles(&profiles);
1001  return guid;
1002}
1003
1004void PersonalDataManager::NotifyPersonalDataChanged() {
1005  FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
1006                    OnPersonalDataChanged());
1007}
1008
1009std::string PersonalDataManager::SaveImportedCreditCard(
1010    const CreditCard& imported_card) {
1011  DCHECK(!imported_card.number().empty());
1012  if (is_off_the_record_)
1013    return std::string();
1014
1015  // Set to true if |imported_card| is merged into the credit card list.
1016  bool merged = false;
1017
1018  std::string guid = imported_card.guid();
1019  std::vector<CreditCard> credit_cards;
1020  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
1021       iter != credit_cards_.end();
1022       ++iter) {
1023    CreditCard* card = *iter;
1024    // If |imported_card| has not yet been merged, check whether it should be
1025    // with the current |card|.
1026    if (!merged && card->UpdateFromImportedCard(imported_card, app_locale_)) {
1027      guid = card->guid();
1028      merged = true;
1029    }
1030
1031    credit_cards.push_back(*card);
1032  }
1033
1034  if (!merged)
1035    credit_cards.push_back(imported_card);
1036
1037  SetCreditCards(&credit_cards);
1038  return guid;
1039}
1040
1041void PersonalDataManager::LogProfileCount() const {
1042  if (!has_logged_profile_count_) {
1043    metric_logger_->LogStoredProfileCount(web_profiles_.size());
1044    has_logged_profile_count_ = true;
1045  }
1046}
1047
1048std::string PersonalDataManager::MostCommonCountryCodeFromProfiles() const {
1049  if (!IsAutofillEnabled())
1050    return std::string();
1051
1052  // Count up country codes from existing profiles.
1053  std::map<std::string, int> votes;
1054  // TODO(estade): can we make this GetProfiles() instead? It seems to cause
1055  // errors in tests on mac trybots. See http://crbug.com/57221
1056  const std::vector<AutofillProfile*>& profiles = web_profiles();
1057  std::vector<std::string> country_codes;
1058  AutofillCountry::GetAvailableCountries(&country_codes);
1059  for (size_t i = 0; i < profiles.size(); ++i) {
1060    std::string country_code = StringToUpperASCII(base::UTF16ToASCII(
1061        profiles[i]->GetRawInfo(ADDRESS_HOME_COUNTRY)));
1062
1063    if (std::find(country_codes.begin(), country_codes.end(), country_code) !=
1064            country_codes.end()) {
1065      // Verified profiles count 100x more than unverified ones.
1066      votes[country_code] += profiles[i]->IsVerified() ? 100 : 1;
1067    }
1068  }
1069
1070  // Take the most common country code.
1071  if (!votes.empty()) {
1072    std::map<std::string, int>::iterator iter =
1073        std::max_element(votes.begin(), votes.end(), CompareVotes);
1074    return iter->first;
1075  }
1076
1077  return std::string();
1078}
1079
1080void PersonalDataManager::EnabledPrefChanged() {
1081  default_country_code_.clear();
1082  NotifyPersonalDataChanged();
1083}
1084
1085}  // namespace autofill
1086