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