autofill_manager.cc revision bc7e0823f37810f402bf7f115ee7ccd673f5ac34
1// Copyright (c) 2010 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/autofill_manager.h" 6 7#include <limits> 8#include <string> 9 10#include "base/basictypes.h" 11#include "base/string16.h" 12#include "base/utf_string_conversions.h" 13#ifndef ANDROID 14#include "chrome/browser/autofill/autofill_cc_infobar_delegate.h" 15#endif 16#include "chrome/browser/autofill/autofill_dialog.h" 17#include "chrome/browser/autofill/form_structure.h" 18#include "chrome/browser/autofill/select_control_handler.h" 19#include "chrome/browser/prefs/pref_service.h" 20#include "chrome/browser/profile.h" 21#ifndef ANDROID 22#include "chrome/browser/renderer_host/render_view_host.h" 23#endif 24#include "chrome/browser/tab_contents/tab_contents.h" 25#include "chrome/common/chrome_switches.h" 26#include "chrome/common/pref_names.h" 27#include "chrome/common/url_constants.h" 28#include "webkit/glue/form_data.h" 29#ifdef ANDROID 30#include <WebCoreSupport/autofill/FormFieldAndroid.h> 31#else 32#include "webkit/glue/form_field.h" 33#endif 34 35using webkit_glue::FormData; 36using webkit_glue::FormField; 37 38namespace { 39 40// We only send a fraction of the forms to upload server. 41// The rate for positive/negative matches potentially could be different. 42const double kAutoFillPositiveUploadRateDefaultValue = 0.01; 43const double kAutoFillNegativeUploadRateDefaultValue = 0.01; 44 45// Size and offset of the prefix and suffix portions of phone numbers. 46const int kAutoFillPhoneNumberPrefixOffset = 0; 47const int kAutoFillPhoneNumberPrefixCount = 3; 48const int kAutoFillPhoneNumberSuffixOffset = 3; 49const int kAutoFillPhoneNumberSuffixCount = 4; 50 51const string16::value_type kCreditCardPrefix[] = {'*',0}; 52const string16::value_type kLabelSeparator[] = {';',' ','*',0}; 53 54// Combines the |label| string with the last four digits of the credit card 55// |cc|. If one, the other, or both are empty strings we omit the separator. 56string16 CombineLabelAndCreditCard(const string16& label, 57 const CreditCard* cc) { 58 if (label.empty()) 59 return kCreditCardPrefix + cc->LastFourDigits(); 60 else if (cc->LastFourDigits().empty()) 61 return label; 62 else 63 return label + kLabelSeparator + cc->LastFourDigits(); 64} 65 66// Removes duplicate elements whilst preserving original order of |elements| and 67// |unique_ids|. 68void RemoveDuplicateElements( 69 std::vector<string16>* elements, std::vector<int>* unique_ids) { 70 DCHECK_EQ(elements->size(), unique_ids->size()); 71 72 std::vector<string16> elements_copy; 73 std::vector<int> unique_ids_copy; 74 for (size_t i = 0; i < elements->size(); ++i) { 75 const string16& element = (*elements)[i]; 76 77 bool unique = true; 78 for (std::vector<string16>::const_iterator copy_iter 79 = elements_copy.begin(); 80 copy_iter != elements_copy.end(); ++copy_iter) { 81 if (element == *copy_iter) { 82 unique = false; 83 break; 84 } 85 } 86 87 if (unique) { 88 elements_copy.push_back(element); 89 unique_ids_copy.push_back((*unique_ids)[i]); 90 } 91 } 92 93 elements->assign(elements_copy.begin(), elements_copy.end()); 94 unique_ids->assign(unique_ids_copy.begin(), unique_ids_copy.end()); 95} 96 97bool FormIsHTTPS(FormStructure* form) { 98 return form->source_url().SchemeIs(chrome::kHttpsScheme); 99} 100 101} // namespace 102 103// TODO(jhawkins): Maybe this should be in a grd file? 104const char* kAutoFillLearnMoreUrl = 105 "http://www.google.com/support/chrome/bin/answer.py?answer=142893"; 106 107AutoFillManager::AutoFillManager(TabContents* tab_contents) 108 : tab_contents_(tab_contents), 109 personal_data_(NULL), 110 download_manager_(tab_contents_->profile()), 111 disable_download_manager_requests_(false), 112 cc_infobar_(NULL) { 113 DCHECK(tab_contents); 114 115 // |personal_data_| is NULL when using TestTabContents. 116 personal_data_ = 117 tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager(); 118 download_manager_.SetObserver(this); 119} 120 121AutoFillManager::~AutoFillManager() { 122 download_manager_.SetObserver(NULL); 123} 124 125// static 126void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) { 127 prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement); 128} 129 130// static 131void AutoFillManager::RegisterUserPrefs(PrefService* prefs) { 132 prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true); 133#if defined(OS_MACOSX) 134 prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, true); 135#else 136 prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, false); 137#endif 138 prefs->RegisterRealPref(prefs::kAutoFillPositiveUploadRate, 139 kAutoFillPositiveUploadRateDefaultValue); 140 prefs->RegisterRealPref(prefs::kAutoFillNegativeUploadRate, 141 kAutoFillNegativeUploadRateDefaultValue); 142} 143 144void AutoFillManager::FormSubmitted(const FormData& form) { 145 if (!IsAutoFillEnabled()) 146 return; 147 148 if (tab_contents_->profile()->IsOffTheRecord()) 149 return; 150 151 // Don't save data that was submitted through JavaScript. 152 if (!form.user_submitted) 153 return; 154 155 // Grab a copy of the form data. 156 upload_form_structure_.reset(new FormStructure(form)); 157 158 if (!upload_form_structure_->IsAutoFillable()) 159 return; 160 161 // Determine the possible field types and upload the form structure to the 162 // PersonalDataManager. 163 DeterminePossibleFieldTypes(upload_form_structure_.get()); 164 HandleSubmit(); 165} 166 167void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { 168 if (!IsAutoFillEnabled()) 169 return; 170 171 ParseForms(forms); 172} 173 174bool AutoFillManager::GetAutoFillSuggestions(int query_id, 175 bool form_autofilled, 176 const FormField& field) { 177 if (!IsAutoFillEnabled()) 178 return false; 179 180#ifdef ANDROID 181 // TODO: Refactor the Autofill methods for Chrome too so that 182 // they do not neet to get the render view host here 183 AutoFillHost* host = tab_contents_->autofill_host(); 184#else 185 RenderViewHost* host = tab_contents_->render_view_host(); 186#endif 187 if (!host) 188 return false; 189 190 if (personal_data_->profiles().empty() && 191 personal_data_->credit_cards().empty()) 192 return false; 193 194 // Loops through the cached FormStructures looking for the FormStructure that 195 // contains |field| and the associated AutoFillFieldType. 196 FormStructure* form = NULL; 197 AutoFillField* autofill_field = NULL; 198 for (std::vector<FormStructure*>::iterator form_iter = 199 form_structures_.begin(); 200 form_iter != form_structures_.end() && !autofill_field; ++form_iter) { 201 form = *form_iter; 202 203 // Don't send suggestions for forms that aren't auto-fillable. 204 if (!form->IsAutoFillable()) 205 continue; 206 207 for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); 208 iter != form->end(); ++iter) { 209 // The field list is terminated with a NULL AutoFillField, so don't try to 210 // dereference it. 211 if (!*iter) 212 break; 213 214 if ((**iter) == field) { 215 autofill_field = *iter; 216 break; 217 } 218 } 219 } 220 221 if (!autofill_field) 222 return false; 223 224 std::vector<string16> values; 225 std::vector<string16> labels; 226 std::vector<string16> icons; 227 std::vector<int> unique_ids; 228 AutoFillType type(autofill_field->type()); 229 230 // If this form is non-HTTPS, treat billing address fields as regular address 231 // fields. 232 bool handle_billing = FormIsHTTPS(form); 233 234 if (type.group() == AutoFillType::CREDIT_CARD) 235 GetCreditCardSuggestions( 236 form, field, type, &values, &labels, &icons, &unique_ids); 237 else if (type.group() == AutoFillType::ADDRESS_BILLING) 238 GetBillingProfileSuggestions( 239 form, field, type, &values, &labels, &icons, &unique_ids); 240 else 241 GetProfileSuggestions(form, field, type, handle_billing, 242 &values, &labels, &icons, &unique_ids); 243 244 DCHECK_EQ(values.size(), labels.size()); 245 DCHECK_EQ(values.size(), icons.size()); 246 DCHECK_EQ(values.size(), unique_ids.size()); 247 248 // No suggestions. 249 if (values.empty()) 250 return false; 251 252 // If the form is auto-filled and the renderer is querying for suggestions, 253 // then the user is editing the value of a field. In this case, don't display 254 // labels, as that information is redundant. In addition, remove duplicate 255 // values. 256 if (form_autofilled) { 257 RemoveDuplicateElements(&values, &unique_ids); 258 labels.resize(values.size()); 259 icons.resize(values.size()); 260 261 for (size_t i = 0; i < labels.size(); ++i) { 262 labels[i] = string16(); 263 icons[i] = string16(); 264 } 265 } 266 267 host->AutoFillSuggestionsReturned( 268 query_id, values, labels, icons, unique_ids); 269 return true; 270} 271 272bool AutoFillManager::FillAutoFillFormData(int query_id, 273 const FormData& form, 274 int unique_id) { 275 if (!IsAutoFillEnabled()) 276 return false; 277 278#ifdef ANDROID 279 AutoFillHost* host = tab_contents_->autofill_host(); 280#else 281 RenderViewHost* host = tab_contents_->render_view_host(); 282#endif 283 if (!host) 284 return false; 285 286 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 287 const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); 288 289 // No data to return if the profiles are empty. 290 if (profiles.empty() && credit_cards.empty()) 291 return false; 292 293 // Find the FormStructure that corresponds to |form|. 294 FormData result = form; 295 FormStructure* form_structure = NULL; 296 for (std::vector<FormStructure*>::const_iterator iter = 297 form_structures_.begin(); 298 iter != form_structures_.end(); ++iter) { 299 if (**iter == form) { 300 form_structure = *iter; 301 break; 302 } 303 } 304 305 if (!form_structure) 306 return false; 307 308 // No data to return if there are no auto-fillable fields. 309 if (!form_structure->autofill_count()) 310 return false; 311 312 // Unpack the |unique_id| into component parts. 313 int cc_id = 0; 314 int profile_id = 0; 315 UnpackIDs(unique_id, &cc_id, &profile_id); 316 317 // Find the profile that matches the |profile_id|, if one is specified. 318 const AutoFillProfile* profile = NULL; 319 if (profile_id != 0) { 320 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 321 iter != profiles.end(); ++iter) { 322 if ((*iter)->unique_id() == profile_id) { 323 profile = *iter; 324 break; 325 } 326 } 327 } 328 329 // Find the credit card that matches the |cc_id|, if one is specified. 330 const CreditCard* credit_card = NULL; 331 if (cc_id != 0) { 332 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); 333 iter != credit_cards.end(); ++iter) { 334 if ((*iter)->unique_id() == cc_id) { 335 credit_card = *iter; 336 break; 337 } 338 } 339 } 340 341 if (!profile && !credit_card) 342 return false; 343 344 // The list of fields in |form_structure| and |result.fields| often match 345 // directly and we can fill these corresponding fields; however, when the 346 // |form_structure| and |result.fields| do not match directly we search 347 // ahead in the |form_structure| for the matching field. 348 // See unit tests: AutoFillManagerTest.FormChangesRemoveField and 349 // AutoFillManagerTest.FormChangesAddField for usage. 350 for (size_t i = 0, j = 0; 351 i < form_structure->field_count() && j < result.fields.size(); 352 j++) { 353 size_t k = i; 354 355 // Search forward in the |form_structure| for a corresponding field. 356 while (k < form_structure->field_count() && 357 *form_structure->field(k) != result.fields[j]) { 358 k++; 359 } 360 361 // If we've found a match then fill the |result| field with the found 362 // field in the |form_structure|. 363 if (k >= form_structure->field_count()) 364 continue; 365 366 const AutoFillField* field = form_structure->field(k); 367 AutoFillType autofill_type(field->type()); 368 if (credit_card && 369 autofill_type.group() == AutoFillType::CREDIT_CARD) { 370 FillCreditCardFormField(credit_card, autofill_type, &result.fields[j]); 371 } else if (credit_card && 372 autofill_type.group() == AutoFillType::ADDRESS_BILLING) { 373 FillBillingFormField(credit_card, autofill_type, &result.fields[j]); 374 } else if (profile) { 375 FillFormField(profile, autofill_type, &result.fields[j]); 376 } 377 378 // We found a matching field in the |form_structure| so we 379 // proceed to the next |result| field, and the next |form_structure|. 380 ++i; 381 } 382 autofilled_forms_signatures_.push_front(form_structure->FormSignature()); 383 384 host->AutoFillFormDataFilled(query_id, result); 385 return true; 386} 387 388void AutoFillManager::ShowAutoFillDialog() { 389#ifndef ANDROID 390 ::ShowAutoFillDialog(tab_contents_->GetContentNativeView(), 391 personal_data_, 392 tab_contents_->profile()->GetOriginalProfile()); 393#endif 394} 395 396void AutoFillManager::Reset() { 397 upload_form_structure_.reset(); 398 form_structures_.reset(); 399} 400 401void AutoFillManager::OnLoadedAutoFillHeuristics( 402 const std::string& heuristic_xml) { 403 // TODO(jhawkins): Store |upload_required| in the AutoFillManager. 404 UploadRequired upload_required; 405 FormStructure::ParseQueryResponse(heuristic_xml, 406 form_structures_.get(), 407 &upload_required); 408} 409 410void AutoFillManager::OnUploadedAutoFillHeuristics( 411 const std::string& form_signature) { 412} 413 414void AutoFillManager::OnHeuristicsRequestError( 415 const std::string& form_signature, 416 AutoFillDownloadManager::AutoFillRequestType request_type, 417 int http_error) { 418} 419 420bool AutoFillManager::IsAutoFillEnabled() const { 421#ifdef ANDROID 422 // TODO: This should be a setting in the android UI. 423 return true; 424#endif 425 PrefService* prefs = tab_contents_->profile()->GetPrefs(); 426 427 // Migrate obsolete AutoFill pref. 428 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { 429 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); 430 prefs->ClearPref(prefs::kFormAutofillEnabled); 431 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); 432 return enabled; 433 } 434 435 return prefs->GetBoolean(prefs::kAutoFillEnabled); 436} 437 438void AutoFillManager::DeterminePossibleFieldTypes( 439 FormStructure* form_structure) { 440 for (size_t i = 0; i < form_structure->field_count(); i++) { 441 const AutoFillField* field = form_structure->field(i); 442 FieldTypeSet field_types; 443 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); 444 form_structure->set_possible_types(i, field_types); 445 } 446} 447 448void AutoFillManager::HandleSubmit() { 449 // If there wasn't enough data to import then we don't want to send an upload 450 // to the server. 451 // TODO(jhawkins): Import form data from |form_structures_|. That will 452 // require querying the FormManager for updated field values. 453 std::vector<FormStructure*> import; 454 import.push_back(upload_form_structure_.get()); 455 if (!personal_data_->ImportFormData(import, this)) 456 return; 457 458 // Did we get credit card info? 459 AutoFillProfile* profile; 460 CreditCard* credit_card; 461 personal_data_->GetImportedFormData(&profile, &credit_card); 462 463 if (!credit_card) { 464 UploadFormData(); 465 return; 466 } 467 468#ifndef ANDROID 469 // Show an infobar to offer to save the credit card info. 470 if (tab_contents_) { 471 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, 472 this)); 473 } 474#endif 475} 476 477void AutoFillManager::UploadFormData() { 478 if (!disable_download_manager_requests_ && upload_form_structure_.get()) { 479 bool was_autofilled = false; 480 // Check if the form among last 3 forms that were auto-filled. 481 // Clear older signatures. 482 std::list<std::string>::iterator it; 483 int total_form_checked = 0; 484 for (it = autofilled_forms_signatures_.begin(); 485 it != autofilled_forms_signatures_.end() && total_form_checked < 3; 486 ++it, ++total_form_checked) { 487 if (*it == upload_form_structure_->FormSignature()) 488 was_autofilled = true; 489 } 490 // Remove outdated form signatures. 491 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { 492 autofilled_forms_signatures_.erase(it, 493 autofilled_forms_signatures_.end()); 494 } 495 download_manager_.StartUploadRequest(*(upload_form_structure_.get()), 496 was_autofilled); 497 } 498} 499 500void AutoFillManager::OnInfoBarClosed(bool should_save) { 501 if (should_save) 502 personal_data_->SaveImportedCreditCard(); 503 UploadFormData(); 504} 505 506AutoFillManager::AutoFillManager() 507 : tab_contents_(NULL), 508 personal_data_(NULL), 509 download_manager_(NULL), 510 disable_download_manager_requests_(false), 511 cc_infobar_(NULL) { 512} 513 514AutoFillManager::AutoFillManager(TabContents* tab_contents, 515 PersonalDataManager* personal_data) 516 : tab_contents_(tab_contents), 517 personal_data_(personal_data), 518 download_manager_(NULL), 519 disable_download_manager_requests_(false), 520 cc_infobar_(NULL) { 521 DCHECK(tab_contents); 522} 523 524void AutoFillManager::GetProfileSuggestions(FormStructure* form, 525 const FormField& field, 526 AutoFillType type, 527 bool include_cc_labels, 528 std::vector<string16>* values, 529 std::vector<string16>* labels, 530 std::vector<string16>* icons, 531 std::vector<int>* unique_ids) { 532 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 533 std::vector<AutoFillProfile*> matched_profiles; 534 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 535 iter != profiles.end(); ++iter) { 536 AutoFillProfile* profile = *iter; 537 538 // The value of the stored data for this field type in the |profile|. 539 string16 profile_field_value = profile->GetFieldText(type); 540 541 if (!profile_field_value.empty() && 542 StartsWith(profile_field_value, field.value(), false)) { 543 matched_profiles.push_back(profile); 544 values->push_back(profile_field_value); 545 unique_ids->push_back(PackIDs(0, profile->unique_id())); 546 } 547 } 548 549 AutoFillProfile::CreateInferredLabels(&matched_profiles, labels, 0, 550 type.field_type()); 551 552 if (!include_cc_labels || !form->HasBillingFields() || !FormIsHTTPS(form)) { 553 icons->resize(values->size()); // No CC, so no icons. 554 return; 555 } 556 557 size_t i = 0; 558 std::vector<string16> expanded_values; 559 std::vector<string16> expanded_labels; 560 std::vector<int> expanded_ids; 561 for (std::vector<AutoFillProfile*>::const_iterator iter = 562 matched_profiles.begin(); iter != matched_profiles.end(); 563 ++iter, ++i) { 564 AutoFillProfile* profile = *iter; 565 for (std::vector<CreditCard*>::const_iterator cc = 566 personal_data_->credit_cards().begin(); 567 cc != personal_data_->credit_cards().end(); ++cc) { 568 expanded_values.push_back((*values)[i]); 569 string16 label = CombineLabelAndCreditCard((*labels)[i], *cc); 570 expanded_labels.push_back(label); 571 icons->push_back((*cc)->type()); 572 expanded_ids.push_back(PackIDs((*cc)->unique_id(), profile->unique_id())); 573 } 574 } 575 576 expanded_labels.swap(*labels); 577 expanded_values.swap(*values); 578 expanded_ids.swap(*unique_ids); 579} 580 581void AutoFillManager::GetBillingProfileSuggestions( 582 FormStructure* form, 583 const FormField& field, 584 AutoFillType type, 585 std::vector<string16>* values, 586 std::vector<string16>* labels, 587 std::vector<string16>* icons, 588 std::vector<int>* unique_ids) { 589 590 // If the form is non-HTTPS, no CC suggestions are provided; however, give the 591 // user the option of filling the billing address fields with regular address 592 // data. 593 if (!FormIsHTTPS(form)) { 594 GetProfileSuggestions( 595 form, field, type, false, values, icons, labels, unique_ids); 596 return; 597 } 598 599 std::vector<CreditCard*> matching_creditcards; 600 std::vector<AutoFillProfile*> matching_profiles; 601 602 // Collect matching pairs of credit cards and related profiles, where profile 603 // field value matches form field value. 604 for (std::vector<CreditCard*>::const_iterator cc = 605 personal_data_->credit_cards().begin(); 606 cc != personal_data_->credit_cards().end(); ++cc) { 607 int billing_address_id = (*cc)->billing_address_id(); 608 AutoFillProfile* billing_profile = NULL; 609 610 // The value of the stored data for this field type in the |profile|. 611 string16 profile_field_value; 612 613 for (std::vector<AutoFillProfile*>::const_iterator iter = 614 personal_data_->profiles().begin(); 615 iter != personal_data_->profiles().end(); ++iter) { 616 AutoFillProfile* profile = *iter; 617 618 // This assumes that labels are unique. 619 if (profile->unique_id() == billing_address_id && 620 !profile->GetFieldText(type).empty() && 621 StartsWith(profile->GetFieldText(type), field.value(), false)) { 622 billing_profile = profile; 623 break; 624 } 625 } 626 627 if (!billing_profile) 628 continue; 629 630 matching_creditcards.push_back(*cc); 631 matching_profiles.push_back(billing_profile); 632 } 633 634 std::vector<string16> inferred_labels; 635 AutoFillProfile::CreateInferredLabels(&matching_profiles, &inferred_labels, 0, 636 type.field_type()); 637 638 DCHECK_EQ(matching_profiles.size(), matching_creditcards.size()); 639 DCHECK_EQ(matching_profiles.size(), inferred_labels.size()); 640 641 // Process the matching pairs into suggested |values|, |labels|, and 642 // |unique_ids|. 643 for (size_t i = 0; i < matching_profiles.size(); ++i) { 644 values->push_back(matching_profiles[i]->GetFieldText(type)); 645 string16 label = CombineLabelAndCreditCard(inferred_labels[i], 646 matching_creditcards[i]); 647 labels->push_back(label); 648 icons->push_back(matching_creditcards[i]->type()); 649 unique_ids->push_back(PackIDs(matching_creditcards[i]->unique_id(), 650 matching_profiles[i]->unique_id())); 651 } 652} 653 654void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, 655 const FormField& field, 656 AutoFillType type, 657 std::vector<string16>* values, 658 std::vector<string16>* labels, 659 std::vector<string16>* icons, 660 std::vector<int>* unique_ids) { 661 // Don't return CC suggestions for non-HTTPS pages. 662 if (!FormIsHTTPS(form)) 663 return; 664 665 for (std::vector<CreditCard*>::const_iterator iter = 666 personal_data_->credit_cards().begin(); 667 iter != personal_data_->credit_cards().end(); ++iter) { 668 CreditCard* credit_card = *iter; 669 670 // The value of the stored data for this field type in the |credit_card|. 671 string16 creditcard_field_value = credit_card->GetFieldText(type); 672 if (!creditcard_field_value.empty() && 673 StartsWith(creditcard_field_value, field.value(), false)) { 674 if (type.field_type() == CREDIT_CARD_NUMBER) 675 creditcard_field_value = credit_card->ObfuscatedNumber(); 676 677 if (!form->HasNonBillingFields()) { 678 values->push_back(creditcard_field_value); 679 labels->push_back(CombineLabelAndCreditCard(string16(), credit_card)); 680 icons->push_back(credit_card->type()); 681 unique_ids->push_back(PackIDs(credit_card->unique_id(), 0)); 682 } else { 683 const std::vector<AutoFillProfile*>& profiles 684 = personal_data_->profiles(); 685 std::vector<string16> inferred_labels; 686 AutoFillProfile::CreateInferredLabels(&profiles, 687 &inferred_labels, 688 0, 689 type.field_type()); 690 DCHECK_EQ(profiles.size(), inferred_labels.size()); 691 692 for (size_t i = 0; i < profiles.size(); ++i) { 693 values->push_back(creditcard_field_value); 694 695 string16 label = CombineLabelAndCreditCard(inferred_labels[i], 696 credit_card); 697 labels->push_back(label); 698 icons->push_back(credit_card->type()); 699 unique_ids->push_back( 700 PackIDs(credit_card->unique_id(), profiles[i]->unique_id())); 701 } 702 } 703 } 704 } 705} 706 707void AutoFillManager::FillBillingFormField(const CreditCard* credit_card, 708 AutoFillType type, 709 webkit_glue::FormField* field) { 710 DCHECK(credit_card); 711 DCHECK(type.group() == AutoFillType::ADDRESS_BILLING); 712 DCHECK(field); 713 714 int billing_address_id = credit_card->billing_address_id(); 715 if (billing_address_id != 0) { 716 AutoFillProfile* profile = NULL; 717 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 718 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 719 iter != profiles.end(); ++iter) { 720 if ((*iter)->unique_id() == billing_address_id) { 721 profile = *iter; 722 break; 723 } 724 } 725 726 if (profile) { 727 FillFormField(profile, type, field); 728 } 729 } 730} 731 732void AutoFillManager::FillCreditCardFormField(const CreditCard* credit_card, 733 AutoFillType type, 734 webkit_glue::FormField* field) { 735 DCHECK(credit_card); 736 DCHECK(field); 737 738 if (field->form_control_type() == ASCIIToUTF16("select-one")) 739 autofill::FillSelectControl(credit_card, type, field); 740 else 741 field->set_value(credit_card->GetFieldText(type)); 742} 743 744void AutoFillManager::FillFormField(const AutoFillProfile* profile, 745 AutoFillType type, 746 webkit_glue::FormField* field) { 747 DCHECK(profile); 748 DCHECK(field); 749 750 if (type.subgroup() == AutoFillType::PHONE_NUMBER) { 751 FillPhoneNumberField(profile, field); 752 } else { 753 if (field->form_control_type() == ASCIIToUTF16("select-one")) 754 autofill::FillSelectControl(profile, type, field); 755 else 756 field->set_value(profile->GetFieldText(type)); 757 } 758} 759 760void AutoFillManager::FillSelectOneField(const AutoFillProfile* profile, 761 AutoFillType type, 762 webkit_glue::FormField* field) { 763 DCHECK(profile); 764 DCHECK(field); 765 DCHECK(field->form_control_type() == ASCIIToUTF16("select-one")); 766 string16 selected_string = profile->GetFieldText(type); 767 std::string ascii_value = UTF16ToASCII(selected_string); 768 for (size_t i = 0; i < field->option_strings().size(); ++i) { 769 if (profile->GetFieldText(type) == field->option_strings()[i]) { 770 // An exact match - use it. 771 selected_string = profile->GetFieldText(type); 772 break; 773 } 774 if (!base::strcasecmp(UTF16ToASCII(field->option_strings()[i]).c_str(), 775 ascii_value.c_str())) { 776 // A match, but not in the same case - save it for the case we won't 777 // find an exact match. 778 selected_string = field->option_strings()[i]; 779 } 780 } 781 field->set_value(selected_string); 782} 783 784 785void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile, 786 webkit_glue::FormField* field) { 787 // If we are filling a phone number, check to see if the size field 788 // matches the "prefix" or "suffix" sizes and fill accordingly. 789 string16 number = profile->GetFieldText(AutoFillType(PHONE_HOME_NUMBER)); 790 bool has_valid_suffix_and_prefix = (number.length() == 791 (kAutoFillPhoneNumberPrefixCount + kAutoFillPhoneNumberSuffixCount)); 792 if (has_valid_suffix_and_prefix && 793 field->size() == kAutoFillPhoneNumberPrefixCount) { 794 number = number.substr(kAutoFillPhoneNumberPrefixOffset, 795 kAutoFillPhoneNumberPrefixCount); 796 field->set_value(number); 797 } else if (has_valid_suffix_and_prefix && 798 field->size() == kAutoFillPhoneNumberSuffixCount) { 799 number = number.substr(kAutoFillPhoneNumberSuffixOffset, 800 kAutoFillPhoneNumberSuffixCount); 801 field->set_value(number); 802 } else { 803 field->set_value(number); 804 } 805} 806 807void AutoFillManager::ParseForms( 808 const std::vector<webkit_glue::FormData>& forms) { 809 for (std::vector<FormData>::const_iterator iter = 810 forms.begin(); 811 iter != forms.end(); ++iter) { 812 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); 813 if (!form_structure->ShouldBeParsed()) 814 continue; 815 816 DeterminePossibleFieldTypes(form_structure.get()); 817 form_structures_.push_back(form_structure.release()); 818 } 819 820 // If none of the forms were parsed, no use querying the server. 821 if (!form_structures_.empty() && !disable_download_manager_requests_) 822 download_manager_.StartQueryRequest(form_structures_); 823} 824 825// When sending IDs (across processes) to the renderer we pack credit card and 826// profile IDs into a single integer. Credit card IDs are sent in the high 827// word and profile IDs are sent in the low word. 828// static 829int AutoFillManager::PackIDs(int cc_id, int profile_id) { 830 DCHECK(cc_id <= std::numeric_limits<unsigned short>::max()); 831 DCHECK(profile_id <= std::numeric_limits<unsigned short>::max()); 832 833 return cc_id << std::numeric_limits<unsigned short>::digits | profile_id; 834} 835 836// When receiving IDs (across processes) from the renderer we unpack credit card 837// and profile IDs from a single integer. Credit card IDs are stored in the 838// high word and profile IDs are stored in the low word. 839// static 840void AutoFillManager::UnpackIDs(int id, int* cc_id, int* profile_id) { 841 *cc_id = id >> std::numeric_limits<unsigned short>::digits & 842 std::numeric_limits<unsigned short>::max(); 843 *profile_id = id & std::numeric_limits<unsigned short>::max(); 844} 845