Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / personal_data_manager.cc
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:
43   explicit FormGroupMatchesByGUIDFunctor(const std::string& guid)
44       : guid_(guid) {
45   }
46
47   bool operator()(const T& form_group) {
48     return form_group.guid() == guid_;
49   }
50
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>
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>
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:
75   explicit IsEmptyFunctor(const std::string& app_locale)
76       : app_locale_(app_locale) {
77   }
78
79   bool operator()(const T& form_group) {
80     return form_group.IsEmpty(app_locale_);
81   }
82
83  private:
84   const std::string app_locale_;
85 };
86
87 // Returns true if minimum requirements for import of a given |profile| have
88 // been met.  An address submitted via a form must have at least the fields
89 // required as determined by its country code.
90 // No verification of validity of the contents is preformed. This is an
91 // existence check only.
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.
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.
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
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
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
180 PersonalDataManager::~PersonalDataManager() {
181   CancelPendingQuery(&pending_profiles_query_);
182   CancelPendingQuery(&pending_creditcards_query_);
183
184   if (database_.get())
185     database_->RemoveObserver(this);
186 }
187
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
220 void PersonalDataManager::AutofillMultipleChanged() {
221   Refresh();
222 }
223
224 void PersonalDataManager::AddObserver(PersonalDataManagerObserver* observer) {
225   observers_.AddObserver(observer);
226 }
227
228 void PersonalDataManager::RemoveObserver(
229     PersonalDataManagerObserver* observer) {
230   observers_.RemoveObserver(observer);
231 }
232
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
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
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
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
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
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
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
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
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
530 bool PersonalDataManager::IsDataLoaded() const {
531   return is_data_loaded_;
532 }
533
534 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles() const {
535   return GetProfiles(false);
536 }
537
538 const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() const {
539   return web_profiles_.get();
540 }
541
542 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
543   return credit_cards_.get();
544 }
545
546 void PersonalDataManager::Refresh() {
547   LoadProfiles();
548   LoadCreditCards();
549 }
550
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
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
699 bool PersonalDataManager::IsAutofillEnabled() const {
700   DCHECK(pref_service_);
701   return pref_service_->GetBoolean(prefs::kAutofillEnabled);
702 }
703
704 std::string PersonalDataManager::CountryCodeForCurrentTimezone() const {
705   return base::CountryCodeForCurrentTimezone();
706 }
707
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
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
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
782 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
808 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
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
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
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)
932 void PersonalDataManager::LoadAuxiliaryProfiles(bool record_metrics) const {
933 }
934 #endif
935
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
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
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
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
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
1017 void PersonalDataManager::NotifyPersonalDataChanged() {
1018   FOR_EACH_OBSERVER(PersonalDataManagerObserver, observers_,
1019                     OnPersonalDataChanged());
1020 }
1021
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
1054 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
1061 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
1093 void PersonalDataManager::EnabledPrefChanged() {
1094   default_country_code_.clear();
1095   NotifyPersonalDataChanged();
1096 }
1097
1098 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