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