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