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