autofill_manager.cc revision ec088f53b6595e64df8841a817706e6d086cb17c
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#ifdef ANDROID 206 AutoFillHost* host = NULL; 207#else 208 RenderViewHost* host = NULL; 209#endif 210 FormStructure* form_structure = NULL; 211 AutoFillField* autofill_field = NULL; 212 if (!GetHost(personal_data_->profiles(), 213 personal_data_->credit_cards(), 214 &host) || 215 !FindCachedFormAndField(form, field, &form_structure, &autofill_field)) 216 return false; 217 218 DCHECK(host); 219 DCHECK(form_structure); 220 DCHECK(autofill_field); 221 222 // Don't send suggestions for forms that aren't auto-fillable. 223 if (!form_structure->IsAutoFillable(false)) 224 return false; 225 226 std::vector<string16> values; 227 std::vector<string16> labels; 228 std::vector<string16> icons; 229 std::vector<int> unique_ids; 230 231 AutoFillType type(autofill_field->type()); 232 bool is_filling_credit_card = (type.group() == AutoFillType::CREDIT_CARD); 233 if (is_filling_credit_card) { 234 GetCreditCardSuggestions( 235 form_structure, field, type, &values, &labels, &icons, &unique_ids); 236 } else { 237 GetProfileSuggestions( 238 form_structure, field, type, &values, &labels, &icons, &unique_ids); 239 } 240 241 DCHECK_EQ(values.size(), labels.size()); 242 DCHECK_EQ(values.size(), icons.size()); 243 DCHECK_EQ(values.size(), unique_ids.size()); 244 245 // No suggestions. 246 if (values.empty()) 247 return false; 248 249#ifndef ANDROID 250 // Don't provide AutoFill suggestions when AutoFill is disabled, and don't 251 // provide credit card suggestions for non-HTTPS pages. However, provide a 252 // warning to the user in these cases. 253 int warning = 0; 254 if (!form_structure->IsAutoFillable(true)) 255 warning = IDS_AUTOFILL_WARNING_FORM_DISABLED; 256 else if (is_filling_credit_card && !FormIsHTTPS(form_structure)) 257 warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION; 258 if (warning) { 259 values.assign(1, l10n_util::GetStringUTF16(warning)); 260 labels.assign(1, string16()); 261 icons.assign(1, string16()); 262 unique_ids.assign(1, -1); 263 host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); 264 return true; 265 } 266#endif 267 268 // If the form is auto-filled and the renderer is querying for suggestions, 269 // then the user is editing the value of a field. In this case, mimick 270 // autocomplete: don't display or icons, as that information is redundant. 271 if (FormIsAutoFilled(form_structure, form, is_filling_credit_card)) { 272 labels.assign(labels.size(), string16()); 273 icons.assign(icons.size(), string16()); 274 } 275 276 RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids); 277 host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); 278 return true; 279} 280 281bool AutoFillManager::FillAutoFillFormData(int query_id, 282 const FormData& form, 283 const FormField& field, 284 int unique_id) { 285 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 286 const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); 287#ifdef ANDROID 288 AutoFillHost* host = NULL; 289#else 290 RenderViewHost* host = NULL; 291#endif 292 FormStructure* form_structure = NULL; 293 AutoFillField* autofill_field = NULL; 294 if (!GetHost(profiles, credit_cards, &host) || 295 !FindCachedFormAndField(form, field, &form_structure, &autofill_field)) 296 return false; 297 298 DCHECK(host); 299 DCHECK(form_structure); 300 DCHECK(autofill_field); 301 302 // Unpack the |unique_id| into component parts. 303 std::string cc_guid; 304 std::string profile_guid; 305 UnpackGUIDs(unique_id, &cc_guid, &profile_guid); 306 DCHECK(!guid::IsValidGUID(cc_guid) || !guid::IsValidGUID(profile_guid)); 307 308 // Find the profile that matches the |profile_id|, if one is specified. 309 const AutoFillProfile* profile = NULL; 310 if (guid::IsValidGUID(profile_guid)) { 311 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 312 iter != profiles.end(); ++iter) { 313 if ((*iter)->guid() == profile_guid) { 314 profile = *iter; 315 break; 316 } 317 } 318 DCHECK(profile); 319 } 320 321 // Find the credit card that matches the |cc_id|, if one is specified. 322 const CreditCard* credit_card = NULL; 323 if (guid::IsValidGUID(cc_guid)) { 324 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); 325 iter != credit_cards.end(); ++iter) { 326 if ((*iter)->guid() == cc_guid) { 327 credit_card = *iter; 328 break; 329 } 330 } 331 DCHECK(credit_card); 332 } 333 334 if (!profile && !credit_card) 335 return false; 336 337 FormData result = form; 338 339 // If the form is auto-filled, we should fill |field| but not the rest of the 340 // form. 341 if (FormIsAutoFilled(form_structure, form, (credit_card != NULL))) { 342 for (std::vector<FormField>::iterator iter = result.fields.begin(); 343 iter != result.fields.end(); ++iter) { 344 if ((*iter) == field) { 345 AutoFillType autofill_type(autofill_field->type()); 346 if (credit_card && 347 autofill_type.group() == AutoFillType::CREDIT_CARD) { 348 FillCreditCardFormField(credit_card, autofill_type, &(*iter)); 349 } else if (profile && 350 autofill_type.group() != AutoFillType::CREDIT_CARD) { 351 FillFormField(profile, autofill_type, &(*iter)); 352 } 353 break; 354 } 355 } 356 357 host->AutoFillFormDataFilled(query_id, result); 358 return true; 359 } 360 361 // The list of fields in |form_structure| and |result.fields| often match 362 // directly and we can fill these corresponding fields; however, when the 363 // |form_structure| and |result.fields| do not match directly we search 364 // ahead in the |form_structure| for the matching field. 365 // See unit tests: AutoFillManagerTest.FormChangesRemoveField and 366 // AutoFillManagerTest.FormChangesAddField for usage. 367 for (size_t i = 0, j = 0; 368 i < form_structure->field_count() && j < result.fields.size(); 369 j++) { 370 size_t k = i; 371 372 // Search forward in the |form_structure| for a corresponding field. 373 while (k < form_structure->field_count() && 374 *form_structure->field(k) != result.fields[j]) { 375 k++; 376 } 377 378 // If we've found a match then fill the |result| field with the found 379 // field in the |form_structure|. 380 if (k >= form_structure->field_count()) 381 continue; 382 383 const AutoFillField* field = form_structure->field(k); 384 AutoFillType autofill_type(field->type()); 385 if (credit_card && 386 autofill_type.group() == AutoFillType::CREDIT_CARD) { 387 FillCreditCardFormField(credit_card, autofill_type, &result.fields[j]); 388 } else if (profile && 389 autofill_type.group() != AutoFillType::CREDIT_CARD) { 390 FillFormField(profile, autofill_type, &result.fields[j]); 391 } 392 393 // We found a matching field in the |form_structure| so we 394 // proceed to the next |result| field, and the next |form_structure|. 395 ++i; 396 } 397 autofilled_forms_signatures_.push_front(form_structure->FormSignature()); 398 399 host->AutoFillFormDataFilled(query_id, result); 400 return true; 401} 402 403void AutoFillManager::ShowAutoFillDialog() { 404#ifndef ANDROID 405 ::ShowAutoFillDialog(tab_contents_->GetContentNativeView(), 406 personal_data_, 407 tab_contents_->profile()->GetOriginalProfile()); 408#endif 409} 410 411void AutoFillManager::Reset() { 412 upload_form_structure_.reset(); 413 form_structures_.reset(); 414} 415 416void AutoFillManager::OnLoadedAutoFillHeuristics( 417 const std::string& heuristic_xml) { 418 // TODO(jhawkins): Store |upload_required| in the AutoFillManager. 419 UploadRequired upload_required; 420 FormStructure::ParseQueryResponse(heuristic_xml, 421 form_structures_.get(), 422 &upload_required); 423} 424 425void AutoFillManager::OnUploadedAutoFillHeuristics( 426 const std::string& form_signature) { 427} 428 429void AutoFillManager::OnHeuristicsRequestError( 430 const std::string& form_signature, 431 AutoFillDownloadManager::AutoFillRequestType request_type, 432 int http_error) { 433} 434 435bool AutoFillManager::IsAutoFillEnabled() const { 436#ifdef ANDROID 437 // TODO: This should be a setting in the android UI. 438 return true; 439#endif 440 PrefService* prefs = tab_contents_->profile()->GetPrefs(); 441 442 // Migrate obsolete AutoFill pref. 443 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { 444 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); 445 prefs->ClearPref(prefs::kFormAutofillEnabled); 446 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); 447 return enabled; 448 } 449 450 return prefs->GetBoolean(prefs::kAutoFillEnabled); 451} 452 453void AutoFillManager::DeterminePossibleFieldTypes( 454 FormStructure* form_structure) { 455 for (size_t i = 0; i < form_structure->field_count(); i++) { 456 const AutoFillField* field = form_structure->field(i); 457 FieldTypeSet field_types; 458 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); 459 form_structure->set_possible_types(i, field_types); 460 } 461} 462 463void AutoFillManager::HandleSubmit() { 464 // If there wasn't enough data to import then we don't want to send an upload 465 // to the server. 466 // TODO(jhawkins): Import form data from |form_structures_|. That will 467 // require querying the FormManager for updated field values. 468 std::vector<FormStructure*> import; 469 import.push_back(upload_form_structure_.get()); 470 if (!personal_data_->ImportFormData(import)) 471 return; 472 473 // Did we get credit card info? 474 AutoFillProfile* profile; 475 CreditCard* credit_card; 476 personal_data_->GetImportedFormData(&profile, &credit_card); 477 478 if (!credit_card) { 479 UploadFormData(); 480 return; 481 } 482 483#ifndef ANDROID 484 // Show an infobar to offer to save the credit card info. 485 if (tab_contents_) { 486 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, 487 this)); 488 } 489#endif 490} 491 492void AutoFillManager::UploadFormData() { 493 if (!disable_download_manager_requests_ && upload_form_structure_.get()) { 494 bool was_autofilled = false; 495 // Check if the form among last 3 forms that were auto-filled. 496 // Clear older signatures. 497 std::list<std::string>::iterator it; 498 int total_form_checked = 0; 499 for (it = autofilled_forms_signatures_.begin(); 500 it != autofilled_forms_signatures_.end() && total_form_checked < 3; 501 ++it, ++total_form_checked) { 502 if (*it == upload_form_structure_->FormSignature()) 503 was_autofilled = true; 504 } 505 // Remove outdated form signatures. 506 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { 507 autofilled_forms_signatures_.erase(it, 508 autofilled_forms_signatures_.end()); 509 } 510 download_manager_.StartUploadRequest(*(upload_form_structure_.get()), 511 was_autofilled); 512 } 513} 514 515void AutoFillManager::OnInfoBarClosed(bool should_save) { 516 if (should_save) 517 personal_data_->SaveImportedCreditCard(); 518 UploadFormData(); 519} 520 521AutoFillManager::AutoFillManager() 522 : tab_contents_(NULL), 523 personal_data_(NULL), 524 download_manager_(NULL), 525 disable_download_manager_requests_(false), 526 cc_infobar_(NULL) { 527} 528 529AutoFillManager::AutoFillManager(TabContents* tab_contents, 530 PersonalDataManager* personal_data) 531 : tab_contents_(tab_contents), 532 personal_data_(personal_data), 533 download_manager_(NULL), 534 disable_download_manager_requests_(false), 535 cc_infobar_(NULL) { 536 DCHECK(tab_contents); 537} 538 539bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles, 540 const std::vector<CreditCard*>& credit_cards, 541#ifdef ANDROID 542 AutoFillHost** host) { 543#else 544 RenderViewHost** host) { 545#endif 546 if (!IsAutoFillEnabled()) 547 return false; 548 549 // No autofill data to return if the profiles are empty. 550 if (profiles.empty() && credit_cards.empty()) 551 return false; 552 553#ifdef ANDROID 554 *host = tab_contents_->autofill_host(); 555#else 556 *host = tab_contents_->render_view_host(); 557#endif 558 if (!(*host)) 559 return false; 560 561 return true; 562} 563 564bool AutoFillManager::FindCachedFormAndField(const FormData& form, 565 const FormField& field, 566 FormStructure** form_structure, 567 AutoFillField** autofill_field) { 568 // Find the FormStructure that corresponds to |form|. 569 *form_structure = NULL; 570 for (std::vector<FormStructure*>::const_iterator iter = 571 form_structures_.begin(); 572 iter != form_structures_.end(); ++iter) { 573 if (**iter == form) { 574 *form_structure = *iter; 575 break; 576 } 577 } 578 579 if (!(*form_structure)) 580 return false; 581 582 // No data to return if there are no auto-fillable fields. 583 if (!(*form_structure)->autofill_count()) 584 return false; 585 586 // Find the AutoFillField that corresponds to |field|. 587 *autofill_field = NULL; 588 for (std::vector<AutoFillField*>::const_iterator iter = 589 (*form_structure)->begin(); 590 iter != (*form_structure)->end(); ++iter) { 591 // The field list is terminated with a NULL AutoFillField, so don't try to 592 // dereference it. 593 if (!*iter) 594 break; 595 596 if ((**iter) == field) { 597 *autofill_field = *iter; 598 break; 599 } 600 } 601 602 if (!(*autofill_field)) 603 return false; 604 605 return true; 606} 607 608void AutoFillManager::GetProfileSuggestions(FormStructure* form, 609 const FormField& field, 610 AutoFillType type, 611 std::vector<string16>* values, 612 std::vector<string16>* labels, 613 std::vector<string16>* icons, 614 std::vector<int>* unique_ids) { 615 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 616 std::vector<AutoFillProfile*> matched_profiles; 617 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 618 iter != profiles.end(); ++iter) { 619 AutoFillProfile* profile = *iter; 620 621 // The value of the stored data for this field type in the |profile|. 622 string16 profile_field_value = profile->GetFieldText(type); 623 624 if (!profile_field_value.empty() && 625 StartsWith(profile_field_value, field.value(), false)) { 626 matched_profiles.push_back(profile); 627 values->push_back(profile_field_value); 628 unique_ids->push_back(PackGUIDs(std::string(), profile->guid())); 629 } 630 } 631 632 std::vector<AutoFillFieldType> form_fields; 633 form_fields.reserve(form->field_count()); 634 for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); 635 iter != form->end(); ++iter) { 636 // The field list is terminated with a NULL AutoFillField, so don't try to 637 // dereference it. 638 if (!*iter) 639 break; 640 form_fields.push_back((*iter)->type()); 641 } 642 643 AutoFillProfile::CreateInferredLabels(&matched_profiles, labels, 1, 644 type.field_type(), &form_fields); 645 646 // No icons for profile suggestions. 647 icons->resize(values->size()); 648} 649 650void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, 651 const FormField& field, 652 AutoFillType type, 653 std::vector<string16>* values, 654 std::vector<string16>* labels, 655 std::vector<string16>* icons, 656 std::vector<int>* unique_ids) { 657 for (std::vector<CreditCard*>::const_iterator iter = 658 personal_data_->credit_cards().begin(); 659 iter != personal_data_->credit_cards().end(); ++iter) { 660 CreditCard* credit_card = *iter; 661 662 // The value of the stored data for this field type in the |credit_card|. 663 string16 creditcard_field_value = credit_card->GetFieldText(type); 664 if (!creditcard_field_value.empty() && 665 StartsWith(creditcard_field_value, field.value(), false)) { 666 if (type.field_type() == CREDIT_CARD_NUMBER) 667 creditcard_field_value = credit_card->ObfuscatedNumber(); 668 669 values->push_back(creditcard_field_value); 670 labels->push_back(kCreditCardPrefix + credit_card->LastFourDigits()); 671 icons->push_back(credit_card->type()); 672 unique_ids->push_back(PackGUIDs(credit_card->guid(), std::string())); 673 } 674 } 675} 676 677void AutoFillManager::FillCreditCardFormField(const CreditCard* credit_card, 678 AutoFillType type, 679 webkit_glue::FormField* field) { 680 DCHECK(credit_card); 681 DCHECK(type.group() == AutoFillType::CREDIT_CARD); 682 DCHECK(field); 683 684 if (field->form_control_type() == ASCIIToUTF16("select-one")) 685 autofill::FillSelectControl(credit_card, type, field); 686 else 687 field->set_value(credit_card->GetFieldText(type)); 688} 689 690void AutoFillManager::FillFormField(const AutoFillProfile* profile, 691 AutoFillType type, 692 webkit_glue::FormField* field) { 693 DCHECK(profile); 694 DCHECK(type.group() != AutoFillType::CREDIT_CARD); 695 DCHECK(field); 696 697 if (type.subgroup() == AutoFillType::PHONE_NUMBER) { 698 FillPhoneNumberField(profile, field); 699 } else { 700 if (field->form_control_type() == ASCIIToUTF16("select-one")) 701 autofill::FillSelectControl(profile, type, field); 702 else 703 field->set_value(profile->GetFieldText(type)); 704 } 705} 706 707void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile, 708 webkit_glue::FormField* field) { 709 // If we are filling a phone number, check to see if the size field 710 // matches the "prefix" or "suffix" sizes and fill accordingly. 711 string16 number = profile->GetFieldText(AutoFillType(PHONE_HOME_NUMBER)); 712 bool has_valid_suffix_and_prefix = (number.length() == 713 static_cast<size_t>(PhoneNumber::kPrefixLength + 714 PhoneNumber::kSuffixLength)); 715 if (has_valid_suffix_and_prefix && 716 field->max_length() == PhoneNumber::kPrefixLength) { 717 number = number.substr(PhoneNumber::kPrefixOffset, 718 PhoneNumber::kPrefixLength); 719 field->set_value(number); 720 } else if (has_valid_suffix_and_prefix && 721 field->max_length() == PhoneNumber::kSuffixLength) { 722 number = number.substr(PhoneNumber::kSuffixOffset, 723 PhoneNumber::kSuffixLength); 724 field->set_value(number); 725 } else { 726 field->set_value(number); 727 } 728} 729 730void AutoFillManager::ParseForms(const std::vector<FormData>& forms) { 731 std::vector<FormStructure *> non_queryable_forms; 732 for (std::vector<FormData>::const_iterator iter = forms.begin(); 733 iter != forms.end(); ++iter) { 734 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); 735 if (!form_structure->ShouldBeParsed(false)) 736 continue; 737 738 DeterminePossibleFieldTypes(form_structure.get()); 739 740 // Set aside forms with method GET so that they are not included in the 741 // query to the server. 742 if (form_structure->ShouldBeParsed(true)) 743 form_structures_.push_back(form_structure.release()); 744 else 745 non_queryable_forms.push_back(form_structure.release()); 746 } 747 748 // If none of the forms were parsed, no use querying the server. 749 if (!form_structures_.empty() && !disable_download_manager_requests_) 750 download_manager_.StartQueryRequest(form_structures_); 751 752 for (std::vector<FormStructure *>::const_iterator iter = 753 non_queryable_forms.begin(); 754 iter != non_queryable_forms.end(); ++iter) { 755 form_structures_.push_back(*iter); 756 } 757} 758 759// When sending IDs (across processes) to the renderer we pack credit card and 760// profile IDs into a single integer. Credit card IDs are sent in the high 761// word and profile IDs are sent in the low word. 762int AutoFillManager::PackGUIDs(const std::string& cc_guid, 763 const std::string& profile_guid) { 764 int cc_id = GUIDToID(cc_guid); 765 int profile_id = GUIDToID(profile_guid); 766 767 DCHECK(cc_id <= std::numeric_limits<unsigned short>::max()); 768 DCHECK(profile_id <= std::numeric_limits<unsigned short>::max()); 769 770 return cc_id << std::numeric_limits<unsigned short>::digits | profile_id; 771} 772 773// When receiving IDs (across processes) from the renderer we unpack credit card 774// and profile IDs from a single integer. Credit card IDs are stored in the 775// high word and profile IDs are stored in the low word. 776void AutoFillManager::UnpackGUIDs(int id, 777 std::string* cc_guid, 778 std::string* profile_guid) { 779 int cc_id = id >> std::numeric_limits<unsigned short>::digits & 780 std::numeric_limits<unsigned short>::max(); 781 int profile_id = id & std::numeric_limits<unsigned short>::max(); 782 783 *cc_guid = IDToGUID(cc_id); 784 *profile_guid = IDToGUID(profile_id); 785} 786 787int AutoFillManager::GUIDToID(const std::string& guid) { 788 static int last_id = 1; 789 790 if (!guid::IsValidGUID(guid)) 791 return 0; 792 793 std::map<std::string, int>::const_iterator iter = guid_id_map_.find(guid); 794 if (iter == guid_id_map_.end()) { 795 guid_id_map_[guid] = last_id; 796 id_guid_map_[last_id] = guid; 797 return last_id++; 798 } else { 799 return iter->second; 800 } 801} 802 803const std::string AutoFillManager::IDToGUID(int id) { 804 if (id == 0) 805 return std::string(); 806 807 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); 808 if (iter == id_guid_map_.end()) { 809 NOTREACHED(); 810 return std::string(); 811 } 812 813 return iter->second; 814} 815