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: 40 explicit FormGroupMatchesByGUIDFunctor(const std::string& guid) 41 : guid_(guid) { 42 } 43 44 bool operator()(const T& form_group) { 45 return form_group.guid() == guid_; 46 } 47 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> 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> 68 const T& operator()(const T_Iterator& iterator) { 69 return *iterator; 70 } 71 }; 72 73 template<typename T> 74 T* address_of(T& v) { 75 return &v; 76 } 77 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. 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. 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 105 PersonalDataManager::~PersonalDataManager() { 106 CancelPendingQuery(&pending_profiles_query_); 107 CancelPendingQuery(&pending_creditcards_query_); 108 } 109 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 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 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. 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 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 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 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. 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 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 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 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. 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 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 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 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 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 624 bool PersonalDataManager::HasPassword() { 625 return !password_hash_.empty(); 626 } 627 628 bool PersonalDataManager::IsDataLoaded() const { 629 return is_data_loaded_; 630 } 631 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 658 const std::vector<AutofillProfile*>& PersonalDataManager::web_profiles() { 659 return web_profiles_.get(); 660 } 661 662 const std::vector<CreditCard*>& PersonalDataManager::credit_cards() { 663 return credit_cards_.get(); 664 } 665 666 void PersonalDataManager::Refresh() { 667 LoadProfiles(); 668 LoadCreditCards(); 669 } 670 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 680 void PersonalDataManager::Init(Profile* profile) { 681 profile_ = profile; 682 metric_logger_->LogIsAutofillEnabledAtStartup(IsAutofillEnabled()); 683 684 LoadProfiles(); 685 LoadCreditCards(); 686 } 687 688 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 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 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 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) 801 void PersonalDataManager::LoadAuxiliaryProfiles() { 802 } 803 #endif 804 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 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 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 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 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 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 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 957 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 964 const AutofillMetrics* PersonalDataManager::metric_logger() const { 965 return metric_logger_.get(); 966 } 967 968 void PersonalDataManager::set_metric_logger( 969 const AutofillMetrics* metric_logger) { 970 metric_logger_.reset(metric_logger); 971 } 972