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