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