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