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