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