1// Copyright (c) 2011 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 "chrome/browser/autofill/personal_data_manager.h"
6
7#include <algorithm>
8#include <iterator>
9
10#include "base/logging.h"
11#include "base/string_number_conversions.h"
12#include "base/utf_string_conversions.h"
13#include "chrome/browser/autofill/autofill-inl.h"
14#include "chrome/browser/autofill/autofill_field.h"
15#include "chrome/browser/autofill/autofill_metrics.h"
16#include "chrome/browser/autofill/form_field.h"
17#include "chrome/browser/autofill/form_structure.h"
18#include "chrome/browser/autofill/phone_number.h"
19#include "chrome/browser/autofill/select_control_handler.h"
20#include "chrome/browser/prefs/pref_service.h"
21#include "chrome/browser/profiles/profile.h"
22#ifndef ANDROID
23#include "chrome/browser/sync/profile_sync_service.h"
24#endif
25#include "chrome/browser/webdata/web_data_service.h"
26#include "chrome/common/pref_names.h"
27#ifndef ANDROID
28#include "content/browser/browser_thread.h"
29#endif
30
31namespace {
32
33// The minimum number of fields that must contain relevant user data before
34// Autofill will attempt to import the data into a credit card.
35const int kMinCreditCardImportSize = 2;
36
37template<typename T>
38class FormGroupMatchesByGUIDFunctor {
39 public:
40  explicit FormGroupMatchesByGUIDFunctor(const std::string& guid)
41      : guid_(guid) {
42  }
43
44  bool operator()(const T& form_group) {
45    return form_group.guid() == guid_;
46  }
47
48  bool operator()(const T* form_group) {
49    return form_group->guid() == guid_;
50  }
51
52 private:
53  std::string guid_;
54};
55
56template<typename T, typename C>
57bool FindByGUID(const C& container, const std::string& guid) {
58  return std::find_if(
59      container.begin(),
60      container.end(),
61      FormGroupMatchesByGUIDFunctor<T>(guid)) != container.end();
62}
63
64template<typename T>
65class DereferenceFunctor {
66 public:
67  template<typename T_Iterator>
68  const T& operator()(const T_Iterator& iterator) {
69    return *iterator;
70  }
71};
72
73template<typename T>
74T* address_of(T& v) {
75  return &v;
76}
77
78bool IsValidEmail(const string16& value) {
79  // This regex is more permissive than the official rfc2822 spec on the
80  // subject, but it does reject obvious non-email addresses.
81  const string16 kEmailPattern = ASCIIToUTF16("^[^@]+@[^@]+\\.[a-z]{2,6}$");
82  return autofill::MatchString(value, kEmailPattern);
83}
84
85// Valid for US zip codes only.
86bool IsValidZip(const string16& value) {
87  // Basic US zip code matching.
88  const string16 kZipPattern = ASCIIToUTF16("^\\d{5}(-\\d{4})?$");
89  return autofill::MatchString(value, kZipPattern);
90}
91
92// Returns true if minimum requirements for import of a given |profile| have
93// been met.  An address submitted via a form must have at least these fields
94// filled.  No verification of validity of the contents is preformed.  This is
95// and existence check only.
96bool IsMinimumAddress(const AutofillProfile& profile) {
97  return !profile.GetInfo(ADDRESS_HOME_LINE1).empty() &&
98         !profile.GetInfo(ADDRESS_HOME_CITY).empty() &&
99         !profile.GetInfo(ADDRESS_HOME_STATE).empty() &&
100         !profile.GetInfo(ADDRESS_HOME_ZIP).empty();
101}
102
103}  // namespace
104
105PersonalDataManager::~PersonalDataManager() {
106  CancelPendingQuery(&pending_profiles_query_);
107  CancelPendingQuery(&pending_creditcards_query_);
108}
109
110void PersonalDataManager::OnWebDataServiceRequestDone(
111    WebDataService::Handle h,
112    const WDTypedResult* result) {
113  DCHECK(pending_profiles_query_ || pending_creditcards_query_);
114
115  if (!result) {
116    // Error from the web database.
117    if (h == pending_creditcards_query_)
118      pending_creditcards_query_ = 0;
119    else if (h == pending_profiles_query_)
120      pending_profiles_query_ = 0;
121    return;
122  }
123
124  DCHECK(result->GetType() == AUTOFILL_PROFILES_RESULT ||
125         result->GetType() == AUTOFILL_CREDITCARDS_RESULT);
126
127  switch (result->GetType()) {
128    case AUTOFILL_PROFILES_RESULT:
129      ReceiveLoadedProfiles(h, result);
130      break;
131    case AUTOFILL_CREDITCARDS_RESULT:
132      ReceiveLoadedCreditCards(h, result);
133      break;
134    default:
135      NOTREACHED();
136  }
137
138  // If both requests have responded, then all personal data is loaded.
139  if (pending_profiles_query_ == 0 && pending_creditcards_query_ == 0) {
140    is_data_loaded_ = true;
141    std::vector<AutofillProfile*> profile_pointers(web_profiles_.size());
142    std::copy(web_profiles_.begin(), web_profiles_.end(),
143              profile_pointers.begin());
144    AutofillProfile::AdjustInferredLabels(&profile_pointers);
145    FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataLoaded());
146  }
147}
148
149/////////////////////////////////////////////////////////////////////////////
150// PersonalDataManager,
151// views::ButtonListener implementations
152void PersonalDataManager::SetObserver(PersonalDataManager::Observer* observer) {
153  // TODO: RemoveObserver is for compatibility with old code, it should be
154  // nuked.
155  observers_.RemoveObserver(observer);
156  observers_.AddObserver(observer);
157}
158
159void PersonalDataManager::RemoveObserver(
160    PersonalDataManager::Observer* observer) {
161  observers_.RemoveObserver(observer);
162}
163
164// The |PersonalDataManager| is set up as a listener of the sync service in
165// |EmptyMigrationTrash| in the case where sync is not yet ready to receive
166// changes.  This method, |OnStateChange| acts as a deferred call to
167// |EmptyMigrationTrash| once the sync service becomes available.
168void PersonalDataManager::OnStateChanged() {
169#ifdef ANDROID
170  return;
171#else
172  if (!profile_ || profile_->IsOffTheRecord())
173    return;
174
175  WebDataService* web_data_service =
176      profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
177  if (!web_data_service) {
178    NOTREACHED();
179    return;
180  }
181
182  ProfileSyncService* sync_service = profile_->GetProfileSyncService();
183  if (!sync_service)
184    return;
185
186  if (sync_service->ShouldPushChanges()) {
187    web_data_service->EmptyMigrationTrash(true);
188    sync_service->RemoveObserver(this);
189  }
190#endif
191}
192
193bool PersonalDataManager::ImportFormData(
194    const std::vector<const FormStructure*>& form_structures,
195    const CreditCard** imported_credit_card) {
196#ifdef ANDROID
197  // TODO: Is this the funcionality that tries to create a profile for the user
198  // based on what they've entered into forms?
199  return false;
200#else
201  scoped_ptr<AutofillProfile> imported_profile(new AutoFillProfile);
202  scoped_ptr<CreditCard> local_imported_credit_card(new CreditCard);
203
204  // Parse the form and construct a profile based on the information that is
205  // possible to import.
206  int importable_credit_card_fields = 0;
207  std::vector<const FormStructure*>::const_iterator iter;
208
209  // Detect and discard forms with multiple fields of the same type.
210  std::set<AutofillFieldType> types_seen;
211
212  for (iter = form_structures.begin(); iter != form_structures.end(); ++iter) {
213    const FormStructure* form = *iter;
214    for (size_t i = 0; i < form->field_count(); ++i) {
215      const AutofillField* field = form->field(i);
216      string16 value = CollapseWhitespace(field->value, false);
217
218      // If we don't know the type of the field, or the user hasn't entered any
219      // information into the field, then skip it.
220      if (!field->IsFieldFillable() || value.empty())
221        continue;
222
223      AutofillFieldType field_type = field->type();
224      FieldTypeGroup group(AutofillType(field_type).group());
225
226      // Abandon the import if two fields of the same type are encountered.
227      // This indicates ambiguous data or miscategorization of types.
228      // Make an exception for PHONE_HOME_NUMBER however as both prefix and
229      // suffix are stored against this type.
230      if (types_seen.count(field_type) &&
231          field_type != PHONE_HOME_NUMBER  &&
232          field_type != PHONE_FAX_NUMBER) {
233        imported_profile.reset();
234        local_imported_credit_card.reset();
235        break;
236      } else {
237        types_seen.insert(field_type);
238      }
239
240      if (group == AutofillType::CREDIT_CARD) {
241        // If the user has a password set, we have no way of setting credit
242        // card numbers.
243        if (!HasPassword()) {
244          if (LowerCaseEqualsASCII(field->form_control_type, "month")) {
245            DCHECK_EQ(CREDIT_CARD_EXP_MONTH, field_type);
246            local_imported_credit_card->SetInfoForMonthInputType(value);
247          } else {
248            if (field_type == CREDIT_CARD_NUMBER) {
249              // Clean up any imported credit card numbers.
250              value = CreditCard::StripSeparators(value);
251            }
252            local_imported_credit_card->SetInfo(field_type, value);
253          }
254          ++importable_credit_card_fields;
255        }
256      } else {
257        // In the case of a phone number, if the whole phone number was entered
258        // into a single field, then parse it and set the sub components.
259        if (AutofillType(field_type).subgroup() ==
260                AutofillType::PHONE_WHOLE_NUMBER) {
261          string16 number;
262          string16 city_code;
263          string16 country_code;
264          PhoneNumber::ParsePhoneNumber(value,
265                                        &number,
266                                        &city_code,
267                                        &country_code);
268          if (number.empty())
269            continue;
270
271          if (group == AutofillType::PHONE_HOME) {
272            imported_profile->SetInfo(PHONE_HOME_COUNTRY_CODE, country_code);
273            imported_profile->SetInfo(PHONE_HOME_CITY_CODE, city_code);
274            imported_profile->SetInfo(PHONE_HOME_NUMBER, number);
275          } else if (group == AutofillType::PHONE_FAX) {
276            imported_profile->SetInfo(PHONE_FAX_COUNTRY_CODE, country_code);
277            imported_profile->SetInfo(PHONE_FAX_CITY_CODE, city_code);
278            imported_profile->SetInfo(PHONE_FAX_NUMBER, number);
279          }
280
281          continue;
282        }
283
284        // Phone and fax numbers can be split across multiple fields, so we
285        // might have already stored the prefix, and now be at the suffix.
286        // If so, combine them to form the full number.
287        if (group == AutofillType::PHONE_HOME ||
288            group == AutofillType::PHONE_FAX) {
289          AutofillFieldType number_type = PHONE_HOME_NUMBER;
290          if (group == AutofillType::PHONE_FAX)
291            number_type = PHONE_FAX_NUMBER;
292
293          string16 stored_number = imported_profile->GetInfo(number_type);
294          if (stored_number.size() ==
295                  static_cast<size_t>(PhoneNumber::kPrefixLength) &&
296              value.size() == static_cast<size_t>(PhoneNumber::kSuffixLength)) {
297            value = stored_number + value;
298          }
299        }
300
301        imported_profile->SetInfo(field_type, value);
302
303        // Reject profiles with invalid country information.
304        if (field_type == ADDRESS_HOME_COUNTRY &&
305            !value.empty() && imported_profile->CountryCode().empty()) {
306          imported_profile.reset();
307          break;
308        }
309      }
310    }
311  }
312
313  // Reject the profile if minimum address and validation requirements are not
314  // met.
315  if (imported_profile.get() && !IsValidLearnableProfile(*imported_profile))
316    imported_profile.reset();
317
318  // Reject the credit card if we did not detect enough filled credit card
319  // fields or if the credit card number does not seem to be valid.
320  if (local_imported_credit_card.get() &&
321      (importable_credit_card_fields < kMinCreditCardImportSize ||
322       !CreditCard::IsValidCreditCardNumber(
323           local_imported_credit_card->GetInfo(CREDIT_CARD_NUMBER)))) {
324    local_imported_credit_card.reset();
325  }
326
327  // Don't import if we already have this info.
328  if (local_imported_credit_card.get()) {
329    for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
330         iter != credit_cards_.end();
331         ++iter) {
332      if (local_imported_credit_card->IsSubsetOf(**iter)) {
333        local_imported_credit_card.reset();
334        break;
335      }
336    }
337  }
338
339  if (imported_profile.get()) {
340    // We always save imported profiles.
341    SaveImportedProfile(*imported_profile);
342  }
343  *imported_credit_card = local_imported_credit_card.release();
344
345  return imported_profile.get() || *imported_credit_card;
346#endif
347}
348
349void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
350  if (profile_->IsOffTheRecord())
351    return;
352
353  // Remove empty profiles from input.
354  profiles->erase(
355      std::remove_if(profiles->begin(), profiles->end(),
356                     std::mem_fun_ref(&AutofillProfile::IsEmpty)),
357      profiles->end());
358
359#ifndef ANDROID
360  // Ensure that profile labels are up to date.  Currently, sync relies on
361  // labels to identify a profile.
362  // TODO(dhollowa): We need to deprecate labels and update the way sync
363  // identifies profiles.
364  std::vector<AutofillProfile*> profile_pointers(profiles->size());
365  std::transform(profiles->begin(), profiles->end(), profile_pointers.begin(),
366      address_of<AutofillProfile>);
367  AutofillProfile::AdjustInferredLabels(&profile_pointers);
368
369  WebDataService* wds = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
370  if (!wds)
371    return;
372
373  // Any profiles that are not in the new profile list should be removed from
374  // the web database.
375  for (std::vector<AutofillProfile*>::const_iterator iter =
376           web_profiles_.begin();
377       iter != web_profiles_.end(); ++iter) {
378    if (!FindByGUID<AutofillProfile>(*profiles, (*iter)->guid()))
379      wds->RemoveAutofillProfile((*iter)->guid());
380  }
381
382  // Update the web database with the existing profiles.
383  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
384       iter != profiles->end(); ++iter) {
385    if (FindByGUID<AutofillProfile>(web_profiles_, iter->guid()))
386      wds->UpdateAutofillProfile(*iter);
387  }
388
389  // Add the new profiles to the web database.  Don't add a duplicate.
390  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
391       iter != profiles->end(); ++iter) {
392    if (!FindByGUID<AutofillProfile>(web_profiles_, iter->guid()) &&
393        !FindByContents(web_profiles_, *iter))
394      wds->AddAutofillProfile(*iter);
395  }
396#endif
397
398  // Copy in the new profiles.
399  web_profiles_.reset();
400  for (std::vector<AutofillProfile>::iterator iter = profiles->begin();
401       iter != profiles->end(); ++iter) {
402    web_profiles_.push_back(new AutofillProfile(*iter));
403  }
404
405  // Read our writes to ensure consistency with the database.
406  Refresh();
407
408  FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged());
409}
410
411void PersonalDataManager::SetCreditCards(
412    std::vector<CreditCard>* credit_cards) {
413#ifndef ANDROID
414  // Android does not do credit cards and does not have a WebDataService.
415  if (profile_->IsOffTheRecord())
416    return;
417
418  // Remove empty credit cards from input.
419  credit_cards->erase(
420      std::remove_if(
421          credit_cards->begin(), credit_cards->end(),
422          std::mem_fun_ref(&CreditCard::IsEmpty)),
423      credit_cards->end());
424
425  WebDataService* wds = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
426  if (!wds)
427    return;
428
429  // Any credit cards that are not in the new credit card list should be
430  // removed.
431  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
432       iter != credit_cards_.end(); ++iter) {
433    if (!FindByGUID<CreditCard>(*credit_cards, (*iter)->guid()))
434      wds->RemoveCreditCard((*iter)->guid());
435  }
436
437  // Update the web database with the existing credit cards.
438  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
439       iter != credit_cards->end(); ++iter) {
440    if (FindByGUID<CreditCard>(credit_cards_, iter->guid()))
441      wds->UpdateCreditCard(*iter);
442  }
443
444  // Add the new credit cards to the web database.  Don't add a duplicate.
445  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
446       iter != credit_cards->end(); ++iter) {
447    if (!FindByGUID<CreditCard>(credit_cards_, iter->guid()) &&
448        !FindByContents(credit_cards_, *iter))
449      wds->AddCreditCard(*iter);
450  }
451
452  // Copy in the new credit cards.
453  credit_cards_.reset();
454  for (std::vector<CreditCard>::iterator iter = credit_cards->begin();
455       iter != credit_cards->end(); ++iter) {
456    credit_cards_.push_back(new CreditCard(*iter));
457  }
458
459  // Read our writes to ensure consistency with the database.
460  Refresh();
461
462  FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged());
463#endif
464}
465
466// TODO(jhawkins): Refactor SetProfiles so this isn't so hacky.
467void PersonalDataManager::AddProfile(const AutofillProfile& profile) {
468  // Don't save a web profile if the data in the profile is a subset of an
469  // auxiliary profile.
470  for (std::vector<AutofillProfile*>::const_iterator iter =
471           auxiliary_profiles_.begin();
472       iter != auxiliary_profiles_.end(); ++iter) {
473    if (profile.IsSubsetOf(**iter))
474      return;
475  }
476
477  std::vector<AutofillProfile> profiles;
478  MergeProfile(profile, web_profiles_.get(), &profiles);
479  SetProfiles(&profiles);
480}
481
482void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
483#ifndef ANDROID
484  WebDataService* wds = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
485  if (!wds)
486    return;
487
488  // Update the cached profile.
489  for (std::vector<AutofillProfile*>::iterator iter = web_profiles_->begin();
490       iter != web_profiles_->end(); ++iter) {
491    if ((*iter)->guid() == profile.guid()) {
492      delete *iter;
493      *iter = new AutofillProfile(profile);
494      break;
495    }
496  }
497
498  // Ensure that profile labels are up to date.
499  AutofillProfile::AdjustInferredLabels(&web_profiles_.get());
500
501  wds->UpdateAutofillProfile(profile);
502  FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged());
503#endif
504}
505
506void PersonalDataManager::RemoveProfile(const std::string& guid) {
507  // TODO(jhawkins): Refactor SetProfiles so this isn't so hacky.
508  std::vector<AutofillProfile> profiles(web_profiles_.size());
509  std::transform(web_profiles_.begin(), web_profiles_.end(),
510                 profiles.begin(),
511                 DereferenceFunctor<AutofillProfile>());
512
513  // Remove the profile that matches |guid|.
514  profiles.erase(
515      std::remove_if(profiles.begin(), profiles.end(),
516                     FormGroupMatchesByGUIDFunctor<AutofillProfile>(guid)),
517      profiles.end());
518
519  SetProfiles(&profiles);
520}
521
522AutofillProfile* PersonalDataManager::GetProfileByGUID(
523    const std::string& guid) {
524  for (std::vector<AutofillProfile*>::iterator iter = web_profiles_->begin();
525       iter != web_profiles_->end(); ++iter) {
526    if ((*iter)->guid() == guid)
527      return *iter;
528  }
529  return NULL;
530}
531
532// TODO(jhawkins): Refactor SetCreditCards so this isn't so hacky.
533void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) {
534  std::vector<CreditCard> credit_cards(credit_cards_.size());
535  std::transform(credit_cards_.begin(), credit_cards_.end(),
536                 credit_cards.begin(),
537                 DereferenceFunctor<CreditCard>());
538
539  credit_cards.push_back(credit_card);
540  SetCreditCards(&credit_cards);
541}
542
543void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
544#ifndef ANDROID
545  WebDataService* wds = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
546  if (!wds)
547    return;
548
549  // Update the cached credit card.
550  for (std::vector<CreditCard*>::iterator iter = credit_cards_->begin();
551       iter != credit_cards_->end(); ++iter) {
552    if ((*iter)->guid() == credit_card.guid()) {
553      delete *iter;
554      *iter = new CreditCard(credit_card);
555      break;
556    }
557  }
558
559  wds->UpdateCreditCard(credit_card);
560  FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged());
561#endif
562}
563
564void PersonalDataManager::RemoveCreditCard(const std::string& guid) {
565  // TODO(jhawkins): Refactor SetCreditCards so this isn't so hacky.
566  std::vector<CreditCard> credit_cards(credit_cards_.size());
567  std::transform(credit_cards_.begin(), credit_cards_.end(),
568                 credit_cards.begin(),
569                 DereferenceFunctor<CreditCard>());
570
571  // Remove the credit card that matches |guid|.
572  credit_cards.erase(
573      std::remove_if(credit_cards.begin(), credit_cards.end(),
574                     FormGroupMatchesByGUIDFunctor<CreditCard>(guid)),
575      credit_cards.end());
576
577  SetCreditCards(&credit_cards);
578}
579
580CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) {
581  for (std::vector<CreditCard*>::iterator iter = credit_cards_.begin();
582       iter != credit_cards_.end(); ++iter) {
583    if ((*iter)->guid() == guid)
584      return *iter;
585  }
586  return NULL;
587}
588
589void PersonalDataManager::GetPossibleFieldTypes(const string16& text,
590                                                FieldTypeSet* possible_types) {
591  string16 clean_info = StringToLowerASCII(CollapseWhitespace(text, false));
592  if (clean_info.empty()) {
593    possible_types->insert(EMPTY_TYPE);
594    return;
595  }
596
597  const std::vector<AutofillProfile*>& profiles = this->profiles();
598  for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
599       iter != profiles.end(); ++iter) {
600    const FormGroup* profile = *iter;
601    if (!profile) {
602      DLOG(ERROR) << "NULL information in profiles list";
603      continue;
604    }
605
606    profile->GetPossibleFieldTypes(clean_info, possible_types);
607  }
608
609  for (ScopedVector<CreditCard>::iterator iter = credit_cards_.begin();
610       iter != credit_cards_.end(); ++iter) {
611    const FormGroup* credit_card = *iter;
612    if (!credit_card) {
613      DLOG(ERROR) << "NULL information in credit cards list";
614      continue;
615    }
616
617    credit_card->GetPossibleFieldTypes(clean_info, possible_types);
618  }
619
620  if (possible_types->empty())
621    possible_types->insert(UNKNOWN_TYPE);
622}
623
624bool PersonalDataManager::HasPassword() {
625  return !password_hash_.empty();
626}
627
628bool PersonalDataManager::IsDataLoaded() const {
629  return is_data_loaded_;
630}
631
632const std::vector<AutofillProfile*>& PersonalDataManager::profiles() {
633  // |profile_| is NULL in AutofillManagerTest.
634#ifdef ANDROID
635  bool auxiliary_profiles_enabled = false;
636#else
637  bool auxiliary_profiles_enabled = profile_ ? profile_->GetPrefs()->GetBoolean(
638      prefs::kAutofillAuxiliaryProfilesEnabled) : false;
639#endif
640  if (!auxiliary_profiles_enabled)
641    return web_profiles();
642
643#if !defined(OS_MACOSX)
644  NOTREACHED() << "Auxiliary profiles supported on Mac only";
645#endif
646
647  profiles_.clear();
648
649  // Populates |auxiliary_profiles_|.
650  LoadAuxiliaryProfiles();
651
652  profiles_.insert(profiles_.end(), web_profiles_.begin(), web_profiles_.end());
653  profiles_.insert(profiles_.end(),
654      auxiliary_profiles_.begin(), auxiliary_profiles_.end());
655  return profiles_;
656}
657
658const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() {
659  return web_profiles_.get();
660}
661
662const std::vector<CreditCard*>& PersonalDataManager::credit_cards() {
663  return credit_cards_.get();
664}
665
666void PersonalDataManager::Refresh() {
667  LoadProfiles();
668  LoadCreditCards();
669}
670
671PersonalDataManager::PersonalDataManager()
672    : profile_(NULL),
673      is_data_loaded_(false),
674      pending_profiles_query_(0),
675      pending_creditcards_query_(0),
676      metric_logger_(new AutofillMetrics),
677      has_logged_profile_count_(false) {
678}
679
680void PersonalDataManager::Init(Profile* profile) {
681  profile_ = profile;
682  metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled());
683
684  LoadProfiles();
685  LoadCreditCards();
686}
687
688bool PersonalDataManager::IsAutofillEnabled() const {
689#ifdef ANDROID
690  return true;
691#else
692  return profile_->GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
693#endif
694}
695
696// static
697bool PersonalDataManager::IsValidLearnableProfile(
698    const AutofillProfile& profile) {
699  if (!IsMinimumAddress(profile))
700    return false;
701
702  string16 email = profile.GetInfo(EMAIL_ADDRESS);
703  if (!email.empty() && !IsValidEmail(email))
704    return false;
705
706  // Reject profiles with invalid US state information.
707  string16 state = profile.GetInfo(ADDRESS_HOME_STATE);
708  if (profile.CountryCode() == "US" &&
709      !state.empty() && !autofill::IsValidState(state)) {
710    return false;
711  }
712
713  // Reject profiles with invalid US zip information.
714  string16 zip = profile.GetInfo(ADDRESS_HOME_ZIP);
715  if (profile.CountryCode() == "US" && !zip.empty() && !IsValidZip(zip))
716    return false;
717
718  return true;
719}
720
721// static
722bool PersonalDataManager::MergeProfile(
723    const AutofillProfile& profile,
724    const std::vector<AutofillProfile*>& existing_profiles,
725    std::vector<AutofillProfile>* merged_profiles) {
726  DCHECK(merged_profiles);
727  merged_profiles->clear();
728
729  // Set to true if |profile| is merged into |existing_profiles|.
730  bool merged = false;
731
732  // First preference is to add missing values to an existing profile.
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    if (!merged) {
738      if (profile.IsSubsetOf(**iter)) {
739        // In this case, the existing profile already contains all of the data
740        // in |profile|, so consider the profiles already merged.
741        merged = true;
742      } else if ((*iter)->IntersectionOfTypesHasEqualValues(profile)) {
743        // |profile| contains all of the data in this profile, plus more.
744        merged = true;
745        (*iter)->MergeWith(profile);
746      }
747    }
748    merged_profiles->push_back(**iter);
749  }
750
751  // The second preference, if not merged above, is to alter non-primary values
752  // where the primary values match.
753  // Again, only merge with the first match.
754  if (!merged) {
755    merged_profiles->clear();
756    for (std::vector<AutofillProfile*>::const_iterator iter =
757             existing_profiles.begin();
758         iter != existing_profiles.end(); ++iter) {
759      if (!merged) {
760        if (!profile.PrimaryValue().empty() &&
761            StringToLowerASCII((*iter)->PrimaryValue()) ==
762                StringToLowerASCII(profile.PrimaryValue())) {
763          merged = true;
764          (*iter)->OverwriteWithOrAddTo(profile);
765        }
766      }
767      merged_profiles->push_back(**iter);
768    }
769  }
770
771  // Finally, if the new profile was not merged with an existing profile then
772  // add the new profile to the list.
773  if (!merged)
774    merged_profiles->push_back(profile);
775
776  return merged;
777}
778
779void PersonalDataManager::LoadProfiles() {
780#ifdef ANDROID
781  // This shoud request the profile(s) from java land on Android.
782  // Call to a java class that would read/write the data in a database.
783  // WebAutoFillClientAndroid will inject a profile while we're testing.
784#else
785  WebDataService* web_data_service =
786      profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
787  if (!web_data_service) {
788    NOTREACHED();
789    return;
790  }
791
792  CancelPendingQuery(&pending_profiles_query_);
793
794  pending_profiles_query_ = web_data_service->GetAutofillProfiles(this);
795#endif
796}
797
798// Win and Linux implementations do nothing.  Mac implementation fills in the
799// contents of |auxiliary_profiles_|.
800#if !defined(OS_MACOSX)
801void PersonalDataManager::LoadAuxiliaryProfiles() {
802}
803#endif
804
805void PersonalDataManager::LoadCreditCards() {
806#ifndef ANDROID
807  // Need a web database service on Android
808  WebDataService* web_data_service =
809      profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
810  if (!web_data_service) {
811    NOTREACHED();
812    return;
813  }
814
815  CancelPendingQuery(&pending_creditcards_query_);
816
817  pending_creditcards_query_ = web_data_service->GetCreditCards(this);
818#endif
819}
820
821void PersonalDataManager::ReceiveLoadedProfiles(WebDataService::Handle h,
822                                                const WDTypedResult* result) {
823  DCHECK_EQ(pending_profiles_query_, h);
824
825  pending_profiles_query_ = 0;
826  web_profiles_.reset();
827
828  const WDResult<std::vector<AutofillProfile*> >* r =
829      static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result);
830
831  std::vector<AutofillProfile*> profiles = r->GetValue();
832  for (std::vector<AutofillProfile*>::iterator iter = profiles.begin();
833       iter != profiles.end(); ++iter) {
834    web_profiles_.push_back(*iter);
835  }
836
837  LogProfileCount();
838  EmptyMigrationTrash();
839}
840
841void PersonalDataManager::ReceiveLoadedCreditCards(
842    WebDataService::Handle h, const WDTypedResult* result) {
843  DCHECK_EQ(pending_creditcards_query_, h);
844
845  pending_creditcards_query_ = 0;
846  credit_cards_.reset();
847
848  const WDResult<std::vector<CreditCard*> >* r =
849      static_cast<const WDResult<std::vector<CreditCard*> >*>(result);
850
851  std::vector<CreditCard*> credit_cards = r->GetValue();
852  for (std::vector<CreditCard*>::iterator iter = credit_cards.begin();
853       iter != credit_cards.end(); ++iter) {
854    credit_cards_.push_back(*iter);
855  }
856}
857
858void PersonalDataManager::CancelPendingQuery(WebDataService::Handle* handle) {
859#ifndef ANDROID
860  // TODO: We need to come up with a web data service class for Android
861  if (*handle) {
862    WebDataService* web_data_service =
863        profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
864    if (!web_data_service) {
865      NOTREACHED();
866      return;
867    }
868    web_data_service->CancelRequest(*handle);
869  }
870  *handle = 0;
871#endif
872}
873
874void PersonalDataManager::SaveImportedProfile(
875    const AutofillProfile& imported_profile) {
876#ifdef ANDROID
877  // TODO: This should update the profile in Java land.
878  return;
879#else
880  if (profile_->IsOffTheRecord())
881    return;
882
883  AddProfile(imported_profile);
884#endif
885}
886
887
888void PersonalDataManager::SaveImportedCreditCard(
889    const CreditCard& imported_credit_card) {
890  if (profile_->IsOffTheRecord())
891    return;
892
893  // Set to true if |imported_credit_card| is merged into the credit card list.
894  bool merged = false;
895
896  std::vector<CreditCard> creditcards;
897  for (std::vector<CreditCard*>::const_iterator iter = credit_cards_.begin();
898       iter != credit_cards_.end();
899       ++iter) {
900    if (imported_credit_card.IsSubsetOf(**iter)) {
901      // In this case, the existing credit card already contains all of the data
902      // in |imported_credit_card|, so consider the credit cards already
903      // merged.
904      merged = true;
905    } else if ((*iter)->IntersectionOfTypesHasEqualValues(
906        imported_credit_card)) {
907      // |imported_credit_card| contains all of the data in this credit card,
908      // plus more.
909      merged = true;
910      (*iter)->MergeWith(imported_credit_card);
911    } else if (!imported_credit_card.number().empty() &&
912               (*iter)->number() == imported_credit_card.number()) {
913      merged = true;
914      (*iter)->OverwriteWith(imported_credit_card);
915    }
916
917    creditcards.push_back(**iter);
918  }
919
920  if (!merged)
921    creditcards.push_back(imported_credit_card);
922
923  SetCreditCards(&creditcards);
924}
925
926void PersonalDataManager::EmptyMigrationTrash() {
927#ifdef ANDROID
928  return;
929#else
930  if (!profile_ || profile_->IsOffTheRecord())
931    return;
932
933  WebDataService* web_data_service =
934      profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
935  if (!web_data_service) {
936    NOTREACHED();
937    return;
938  }
939
940  ProfileSyncService* sync_service = profile_->GetProfileSyncService();
941  if (!sync_service)
942    return;
943
944  if (!sync_service->HasSyncSetupCompleted()) {
945    web_data_service->EmptyMigrationTrash(false);
946  } else if (sync_service->ShouldPushChanges()) {
947    web_data_service->EmptyMigrationTrash(true);
948  } else {
949    // Install ourself as a listener so we can empty the trash once the
950    // sync service becomes available.
951    if (!sync_service->HasObserver(this))
952      sync_service->AddObserver(this);
953  }
954#endif
955}
956
957void PersonalDataManager::LogProfileCount() const {
958  if (!has_logged_profile_count_) {
959    metric_logger_->LogStoredProfileCount(web_profiles_.size());
960    has_logged_profile_count_ = true;
961  }
962}
963
964const AutofillMetrics* PersonalDataManager::metric_logger() const {
965  return metric_logger_.get();
966}
967
968void PersonalDataManager::set_metric_logger(
969    const AutofillMetrics* metric_logger) {
970  metric_logger_.reset(metric_logger);
971}
972