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