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