autofill_manager.cc revision 6e1a1d3242a4de2a633c62ba45948dd2d0620990
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/autofill_manager.h" 6 7#include <limits> 8#include <map> 9#include <set> 10#include <utility> 11 12#include "base/basictypes.h" 13#include "base/command_line.h" 14#include "base/string16.h" 15#include "base/utf_string_conversions.h" 16#ifndef ANDROID 17#include "chrome/browser/autocomplete_history_manager.h" 18#include "chrome/browser/autofill/autofill_cc_infobar_delegate.h" 19#endif 20#include "chrome/browser/autofill/autofill_dialog.h" 21#include "chrome/browser/autofill/autofill_metrics.h" 22#include "chrome/browser/autofill/form_structure.h" 23#include "chrome/browser/autofill/phone_number.h" 24#include "chrome/browser/autofill/select_control_handler.h" 25#include "chrome/browser/prefs/pref_service.h" 26#include "chrome/browser/profiles/profile.h" 27#ifndef ANDROID 28#include "chrome/browser/renderer_host/render_view_host.h" 29#endif 30#include "chrome/browser/tab_contents/tab_contents.h" 31#ifndef ANDROID 32#include "chrome/browser/ui/browser_list.h" 33#include "chrome/common/autofill_messages.h" 34#endif 35#include "chrome/common/chrome_switches.h" 36#include "chrome/common/guid.h" 37#include "chrome/common/notification_details.h" 38#include "chrome/common/notification_service.h" 39#include "chrome/common/notification_type.h" 40#include "chrome/common/pref_names.h" 41#include "chrome/common/url_constants.h" 42#include "grit/generated_resources.h" 43#include "ui/base/l10n/l10n_util.h" 44#include "webkit/glue/form_data.h" 45#ifdef ANDROID 46#include <WebCoreSupport/autofill/FormFieldAndroid.h> 47#else 48#include "webkit/glue/form_field.h" 49#endif 50 51using webkit_glue::FormData; 52using webkit_glue::FormField; 53 54namespace { 55 56// We only send a fraction of the forms to upload server. 57// The rate for positive/negative matches potentially could be different. 58const double kAutoFillPositiveUploadRateDefaultValue = 0.01; 59const double kAutoFillNegativeUploadRateDefaultValue = 0.01; 60 61const string16::value_type kCreditCardPrefix[] = {'*', 0}; 62const string16::value_type kLabelSeparator[] = {';', ' ', '*', 0}; 63 64// Removes duplicate suggestions whilst preserving their original order. 65void RemoveDuplicateSuggestions(std::vector<string16>* values, 66 std::vector<string16>* labels, 67 std::vector<string16>* icons, 68 std::vector<int>* unique_ids) { 69 DCHECK_EQ(values->size(), labels->size()); 70 DCHECK_EQ(values->size(), icons->size()); 71 DCHECK_EQ(values->size(), unique_ids->size()); 72 73 std::set<std::pair<string16, string16> > seen_suggestions; 74 std::vector<string16> values_copy; 75 std::vector<string16> labels_copy; 76 std::vector<string16> icons_copy; 77 std::vector<int> unique_ids_copy; 78 79 for (size_t i = 0; i < values->size(); ++i) { 80 const std::pair<string16, string16> suggestion((*values)[i], (*labels)[i]); 81 if (seen_suggestions.insert(suggestion).second) { 82 values_copy.push_back((*values)[i]); 83 labels_copy.push_back((*labels)[i]); 84 icons_copy.push_back((*icons)[i]); 85 unique_ids_copy.push_back((*unique_ids)[i]); 86 } 87 } 88 89 values->swap(values_copy); 90 labels->swap(labels_copy); 91 icons->swap(icons_copy); 92 unique_ids->swap(unique_ids_copy); 93} 94 95// Precondition: |form| should be the cached version of the form that is to be 96// autofilled, and |field| should be the field in the |form| that corresponds to 97// the initiating field. |is_filling_credit_card| should be true if filling 98// credit card data, false otherwise. 99// Fills |section_start| and |section_end| so that [section_start, section_end) 100// gives the bounds of logical section within |form| that includes |field|. 101// Logical sections are identified by two heuristics: 102// 1. The fields in the section must all be profile or credit card fields, 103// depending on whether |is_filling_credit_card| is true. 104// 2. A logical section should not include multiple fields of the same autofill 105// type (except for phone/fax numbers, as described below). 106void FindSectionBounds(const FormStructure& form, 107 const AutoFillField& field, 108 bool is_filling_credit_card, 109 size_t* section_start, 110 size_t* section_end) { 111 DCHECK(section_start); 112 DCHECK(section_end); 113 114 // By default, the relevant section is the entire form. 115 *section_start = 0; 116 *section_end = form.field_count(); 117 118 std::set<AutoFillFieldType> seen_types; 119 bool initiating_field_is_in_current_section = false; 120 for (size_t i = 0; i < form.field_count(); ++i) { 121 const AutoFillField* current_field = form.field(i); 122 const AutoFillFieldType current_type = 123 AutoFillType::GetEquivalentFieldType(current_field->type()); 124 125 // Fields of unknown type don't help us to distinguish sections. 126 if (current_type == UNKNOWN_TYPE) 127 continue; 128 129 bool already_saw_current_type = seen_types.count(current_type) > 0; 130 // Forms often ask for multiple phone numbers -- e.g. both a daytime and 131 // evening phone number. Our phone and fax number detection is also 132 // generally a little off. Hence, ignore both field types as a signal here. 133 AutoFillType::FieldTypeGroup current_type_group = 134 AutoFillType(current_type).group(); 135 if (current_type_group == AutoFillType::PHONE_HOME || 136 current_type_group == AutoFillType::PHONE_FAX) 137 already_saw_current_type = false; 138 139 // If we are filling credit card data, the relevant section should include 140 // only credit card fields; and similarly for profile data. 141 bool is_credit_card_field = current_type_group == AutoFillType::CREDIT_CARD; 142 bool is_appropriate_type = is_credit_card_field == is_filling_credit_card; 143 144 if (already_saw_current_type || !is_appropriate_type) { 145 if (initiating_field_is_in_current_section) { 146 // We reached the end of the section containing the initiating field. 147 *section_end = i; 148 break; 149 } 150 151 // We reached the end of a section, so start a new section. 152 seen_types.clear(); 153 154 // Only include the current field in the new section if it matches the 155 // type of data we are filling. 156 if (is_appropriate_type) { 157 *section_start = i; 158 } else { 159 *section_start = i + 1; 160 continue; 161 } 162 } 163 164 seen_types.insert(current_type); 165 166 if (current_field == &field) 167 initiating_field_is_in_current_section = true; 168 } 169 170 // We should have found the initiating field. 171 DCHECK(initiating_field_is_in_current_section); 172} 173 174// Precondition: |form_structure| and |form| should correspond to the same 175// logical form. Returns true if the relevant portion of |form| is auto-filled. 176// The "relevant" fields in |form| are ones corresponding to fields in 177// |form_structure| with indices in the range [section_start, section_end). 178bool SectionIsAutoFilled(const FormStructure* form_structure, 179 const webkit_glue::FormData& form, 180 size_t section_start, 181 size_t section_end) { 182 // TODO(isherman): It would be nice to share most of this code with the loop 183 // in |FillAutoFillFormData()|, but I don't see a particularly clean way to do 184 // that. 185 186 // The list of fields in |form_structure| and |form.fields| often match 187 // directly and we can fill these corresponding fields; however, when the 188 // |form_structure| and |form.fields| do not match directly we search 189 // ahead in the |form_structure| for the matching field. 190 for (size_t i = section_start, j = 0; 191 i < section_end && j < form.fields.size(); 192 j++) { 193 size_t k = i; 194 195 // Search forward in the |form_structure| for a corresponding field. 196 while (k < form_structure->field_count() && 197 *form_structure->field(k) != form.fields[j]) { 198 k++; 199 } 200 201 // If we didn't find a match, continue on to the next |form| field. 202 if (k >= form_structure->field_count()) 203 continue; 204 205 AutoFillType autofill_type(form_structure->field(k)->type()); 206 if (form.fields[j].is_autofilled()) 207 return true; 208 209 // We found a matching field in the |form_structure| so we 210 // proceed to the next |form| field, and the next |form_structure|. 211 ++i; 212 } 213 214 return false; 215} 216 217bool FormIsHTTPS(FormStructure* form) { 218 return form->source_url().SchemeIs(chrome::kHttpsScheme); 219} 220 221} // namespace 222 223AutoFillManager::AutoFillManager(TabContents* tab_contents) 224 : tab_contents_(tab_contents), 225 personal_data_(NULL), 226 download_manager_(tab_contents_->profile()), 227 disable_download_manager_requests_(false), 228 metric_logger_(new AutoFillMetrics), 229 cc_infobar_(NULL) { 230 DCHECK(tab_contents); 231 232 // |personal_data_| is NULL when using TestTabContents. 233 personal_data_ = 234 tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager(); 235 download_manager_.SetObserver(this); 236} 237 238AutoFillManager::~AutoFillManager() { 239 download_manager_.SetObserver(NULL); 240} 241 242#ifndef ANDROID 243// static 244void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) { 245 prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement); 246} 247#endif 248 249#ifndef ANDROID 250// static 251void AutoFillManager::RegisterUserPrefs(PrefService* prefs) { 252 prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true); 253#if defined(OS_MACOSX) 254 prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, true); 255#else 256 prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, false); 257#endif 258 prefs->RegisterDoublePref(prefs::kAutoFillPositiveUploadRate, 259 kAutoFillPositiveUploadRateDefaultValue); 260 prefs->RegisterDoublePref(prefs::kAutoFillNegativeUploadRate, 261 kAutoFillNegativeUploadRateDefaultValue); 262} 263#endif 264 265#ifndef ANDROID 266void AutoFillManager::DidNavigateMainFramePostCommit( 267 const NavigationController::LoadCommittedDetails& details, 268 const ViewHostMsg_FrameNavigate_Params& params) { 269 Reset(); 270} 271#endif 272 273#ifndef ANDROID 274bool AutoFillManager::OnMessageReceived(const IPC::Message& message) { 275 bool handled = true; 276 IPC_BEGIN_MESSAGE_MAP(AutoFillManager, message) 277 IPC_MESSAGE_HANDLER(AutoFillHostMsg_FormsSeen, OnFormsSeen) 278 IPC_MESSAGE_HANDLER(AutoFillHostMsg_FormSubmitted, OnFormSubmitted) 279 IPC_MESSAGE_HANDLER(AutoFillHostMsg_QueryFormFieldAutoFill, 280 OnQueryFormFieldAutoFill) 281 IPC_MESSAGE_HANDLER(AutoFillHostMsg_ShowAutoFillDialog, 282 OnShowAutoFillDialog) 283 IPC_MESSAGE_HANDLER(AutoFillHostMsg_FillAutoFillFormData, 284 OnFillAutoFillFormData) 285 IPC_MESSAGE_HANDLER(AutoFillHostMsg_DidFillAutoFillFormData, 286 OnDidFillAutoFillFormData) 287 IPC_MESSAGE_HANDLER(AutoFillHostMsg_DidShowAutoFillSuggestions, 288 OnDidShowAutoFillSuggestions) 289 IPC_MESSAGE_UNHANDLED(handled = false) 290 IPC_END_MESSAGE_MAP() 291 292 return handled; 293} 294#endif 295 296void AutoFillManager::OnFormSubmitted(const FormData& form) { 297 // Let AutoComplete know as well. 298#ifndef ANDROID 299 tab_contents_->autocomplete_history_manager()->OnFormSubmitted(form); 300#endif 301 302 if (!IsAutoFillEnabled()) 303 return; 304 305 if (tab_contents_->profile()->IsOffTheRecord()) 306 return; 307 308 // Don't save data that was submitted through JavaScript. 309 if (!form.user_submitted) 310 return; 311 312 // Grab a copy of the form data. 313 FormStructure submitted_form(form); 314 315 // Disregard forms that we wouldn't ever autofill in the first place. 316 if (!submitted_form.ShouldBeParsed(true)) 317 return; 318 319 DeterminePossibleFieldTypesForUpload(&submitted_form); 320 LogMetricsAboutSubmittedForm(form, &submitted_form); 321 322 UploadFormData(submitted_form); 323 324 if (!submitted_form.IsAutoFillable(true)) 325 return; 326 327 ImportFormData(submitted_form); 328} 329 330void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) { 331 if (!IsAutoFillEnabled()) 332 return; 333 334 ParseForms(forms); 335} 336 337#ifdef ANDROID 338bool AutoFillManager::OnQueryFormFieldAutoFill( 339#else 340void AutoFillManager::OnQueryFormFieldAutoFill( 341#endif 342 int query_id, 343 const webkit_glue::FormData& form, 344 const webkit_glue::FormField& field) { 345 std::vector<string16> values; 346 std::vector<string16> labels; 347 std::vector<string16> icons; 348 std::vector<int> unique_ids; 349 350#ifdef ANDROID 351 AutoFillHost* host = NULL; 352#else 353 RenderViewHost* host = NULL; 354#endif 355 FormStructure* form_structure = NULL; 356 AutoFillField* autofill_field = NULL; 357 if (GetHost( 358 personal_data_->profiles(), personal_data_->credit_cards(), &host) && 359 FindCachedFormAndField(form, field, &form_structure, &autofill_field) && 360 // Don't send suggestions for forms that aren't auto-fillable. 361 form_structure->IsAutoFillable(false)) { 362 AutoFillType type(autofill_field->type()); 363 bool is_filling_credit_card = (type.group() == AutoFillType::CREDIT_CARD); 364 if (is_filling_credit_card) { 365 GetCreditCardSuggestions( 366 form_structure, field, type, &values, &labels, &icons, &unique_ids); 367 } else { 368 GetProfileSuggestions( 369 form_structure, field, type, &values, &labels, &icons, &unique_ids); 370 } 371 372 DCHECK_EQ(values.size(), labels.size()); 373 DCHECK_EQ(values.size(), icons.size()); 374 DCHECK_EQ(values.size(), unique_ids.size()); 375 376 if (!values.empty()) { 377#ifndef ANDROID 378 // Don't provide AutoFill suggestions when AutoFill is disabled, and don't 379 // provide credit card suggestions for non-HTTPS pages. However, provide a 380 // warning to the user in these cases. 381 int warning = 0; 382 if (!form_structure->IsAutoFillable(true)) 383 warning = IDS_AUTOFILL_WARNING_FORM_DISABLED; 384 else if (is_filling_credit_card && !FormIsHTTPS(form_structure)) 385 warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION; 386 if (warning) { 387 values.assign(1, l10n_util::GetStringUTF16(warning)); 388 labels.assign(1, string16()); 389 icons.assign(1, string16()); 390 unique_ids.assign(1, -1); 391 } else { 392 size_t section_start, section_end; 393 FindSectionBounds(*form_structure, *autofill_field, 394 is_filling_credit_card, §ion_start, §ion_end); 395 if (SectionIsAutoFilled(form_structure, form, section_start, 396 section_end)) { 397 // If the relevant section is auto-filled and the renderer is querying 398 // for suggestions, then the user is editing the value of a field. 399 // In this case, mimic autocomplete: don't display labels or icons, 400 // as that information is redundant. 401 labels.assign(labels.size(), string16()); 402 icons.assign(icons.size(), string16()); 403 } 404 405 RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids); 406 } 407#endif 408 } 409#ifdef ANDROID 410 else { 411 return false; 412 } 413#endif 414 } 415#ifdef ANDROID 416 else { 417 return false; 418 } 419#endif 420 421#ifdef ANDROID 422 host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); 423 return true; 424#else 425 // Add the results from AutoComplete. They come back asynchronously, so we 426 // hand off what we generated and they will send the results back to the 427 // renderer. 428 tab_contents_->autocomplete_history_manager()->OnGetAutocompleteSuggestions( 429 query_id, field.name(), field.value(), values, labels, icons, unique_ids); 430#endif 431} 432 433void AutoFillManager::OnFillAutoFillFormData(int query_id, 434 const FormData& form, 435 const FormField& field, 436 int unique_id) { 437 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 438 const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); 439#ifdef ANDROID 440 AutoFillHost* host = NULL; 441#else 442 RenderViewHost* host = NULL; 443#endif 444 FormStructure* form_structure = NULL; 445 AutoFillField* autofill_field = NULL; 446 if (!GetHost(profiles, credit_cards, &host) || 447 !FindCachedFormAndField(form, field, &form_structure, &autofill_field)) 448 return; 449 450 DCHECK(host); 451 DCHECK(form_structure); 452 DCHECK(autofill_field); 453 454 // Unpack the |unique_id| into component parts. 455 std::string cc_guid; 456 std::string profile_guid; 457 UnpackGUIDs(unique_id, &cc_guid, &profile_guid); 458 DCHECK(!guid::IsValidGUID(cc_guid) || !guid::IsValidGUID(profile_guid)); 459 460 // Find the profile that matches the |profile_id|, if one is specified. 461 const AutoFillProfile* profile = NULL; 462 if (guid::IsValidGUID(profile_guid)) { 463 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 464 iter != profiles.end(); ++iter) { 465 if ((*iter)->guid() == profile_guid) { 466 profile = *iter; 467 break; 468 } 469 } 470 DCHECK(profile); 471 } 472 473 // Find the credit card that matches the |cc_id|, if one is specified. 474 const CreditCard* credit_card = NULL; 475 if (guid::IsValidGUID(cc_guid)) { 476 for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); 477 iter != credit_cards.end(); ++iter) { 478 if ((*iter)->guid() == cc_guid) { 479 credit_card = *iter; 480 break; 481 } 482 } 483 DCHECK(credit_card); 484 } 485 486 if (!profile && !credit_card) 487 return; 488 489 // Find the section of the form that we are autofilling. 490 size_t section_start, section_end; 491 FindSectionBounds(*form_structure, *autofill_field, (credit_card != NULL), 492 §ion_start, §ion_end); 493 494 FormData result = form; 495 496 // If the relevant section is auto-filled, we should fill |field| but not the 497 // rest of the form. 498 if (SectionIsAutoFilled(form_structure, form, section_start, section_end)) { 499 for (std::vector<FormField>::iterator iter = result.fields.begin(); 500 iter != result.fields.end(); ++iter) { 501 if ((*iter) == field) { 502 AutoFillType autofill_type(autofill_field->type()); 503 if (profile) { 504 DCHECK(autofill_type.group() != AutoFillType::CREDIT_CARD); 505 FillFormField(profile, autofill_type, &(*iter)); 506 } else { 507 DCHECK(autofill_type.group() == AutoFillType::CREDIT_CARD); 508 FillCreditCardFormField(credit_card, autofill_type, &(*iter)); 509 } 510 break; 511 } 512 } 513 514#ifdef ANDROID 515 host->AutoFillFormDataFilled(query_id, result); 516#else 517 host->Send(new AutoFillMsg_FormDataFilled(host->routing_id(), query_id, 518 result)); 519#endif 520 return; 521 } 522 523 // The list of fields in |form_structure| and |result.fields| often match 524 // directly and we can fill these corresponding fields; however, when the 525 // |form_structure| and |result.fields| do not match directly we search 526 // ahead in the |form_structure| for the matching field. 527 // See unit tests: AutoFillManagerTest.FormChangesRemoveField and 528 // AutoFillManagerTest.FormChangesAddField for usage. 529 for (size_t i = section_start, j = 0; 530 i < section_end && j < result.fields.size(); 531 j++) { 532 size_t k = i; 533 534 // Search forward in the |form_structure| for a corresponding field. 535 while (k < section_end && *form_structure->field(k) != result.fields[j]) { 536 k++; 537 } 538 539 // If we've found a match then fill the |result| field with the found 540 // field in the |form_structure|. 541 if (k >= section_end) 542 continue; 543 544 AutoFillType autofill_type(form_structure->field(k)->type()); 545 if (autofill_type.group() != AutoFillType::NO_GROUP) { 546 if (profile) { 547 DCHECK(autofill_type.group() != AutoFillType::CREDIT_CARD); 548 FillFormField(profile, autofill_type, &result.fields[j]); 549 } else { 550 DCHECK(autofill_type.group() == AutoFillType::CREDIT_CARD); 551 FillCreditCardFormField(credit_card, autofill_type, &result.fields[j]); 552 } 553 } 554 555 // We found a matching field in the |form_structure| so we 556 // proceed to the next |result| field, and the next |form_structure|. 557 ++i; 558 } 559 autofilled_forms_signatures_.push_front(form_structure->FormSignature()); 560 561#ifdef ANDROID 562 host->AutoFillFormDataFilled(query_id, result); 563#else 564 host->Send(new AutoFillMsg_FormDataFilled( 565 host->routing_id(), query_id, result)); 566#endif 567} 568 569void AutoFillManager::OnShowAutoFillDialog() { 570#ifndef ANDROID 571 if (!CommandLine::ForCurrentProcess()->HasSwitch( 572 switches::kDisableTabbedOptions)) { 573 Browser* browser = BrowserList::GetLastActive(); 574 if (browser) 575 browser->ShowOptionsTab(chrome::kAutoFillSubPage); 576 return; 577 } 578 579 ShowAutoFillDialog(tab_contents_->GetContentNativeView(), 580 personal_data_, 581 tab_contents_->profile()->GetOriginalProfile()); 582#endif 583} 584 585void AutoFillManager::OnDidFillAutoFillFormData() { 586#ifndef ANDROID 587 NotificationService::current()->Notify( 588 NotificationType::AUTOFILL_DID_FILL_FORM_DATA, 589 Source<RenderViewHost>(tab_contents_->render_view_host()), 590 NotificationService::NoDetails()); 591#endif 592} 593 594void AutoFillManager::OnDidShowAutoFillSuggestions() { 595#ifndef ANDROID 596 NotificationService::current()->Notify( 597 NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS, 598 Source<RenderViewHost>(tab_contents_->render_view_host()), 599 NotificationService::NoDetails()); 600#endif 601} 602 603void AutoFillManager::OnLoadedAutoFillHeuristics( 604 const std::string& heuristic_xml) { 605 // TODO(jhawkins): Store |upload_required| in the AutoFillManager. 606 UploadRequired upload_required; 607 FormStructure::ParseQueryResponse(heuristic_xml, 608 form_structures_.get(), 609 &upload_required, 610 *metric_logger_); 611} 612 613void AutoFillManager::OnUploadedAutoFillHeuristics( 614 const std::string& form_signature) { 615} 616 617void AutoFillManager::OnHeuristicsRequestError( 618 const std::string& form_signature, 619 AutoFillDownloadManager::AutoFillRequestType request_type, 620 int http_error) { 621} 622 623bool AutoFillManager::IsAutoFillEnabled() const { 624#ifdef ANDROID 625 // TODO: This should be a setting in the android UI. 626 return true; 627#endif 628 PrefService* prefs = tab_contents_->profile()->GetPrefs(); 629 630 // Migrate obsolete AutoFill pref. 631 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { 632 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); 633 prefs->ClearPref(prefs::kFormAutofillEnabled); 634 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); 635 return enabled; 636 } 637 638 return prefs->GetBoolean(prefs::kAutoFillEnabled); 639} 640 641void AutoFillManager::DeterminePossibleFieldTypesForUpload( 642 FormStructure* submitted_form) { 643 for (size_t i = 0; i < submitted_form->field_count(); i++) { 644 const AutoFillField* field = submitted_form->field(i); 645 FieldTypeSet field_types; 646 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); 647 648 DCHECK(!field_types.empty()); 649 submitted_form->set_possible_types(i, field_types); 650 } 651} 652 653void AutoFillManager::LogMetricsAboutSubmittedForm( 654 const FormData& form, 655 const FormStructure* submitted_form) { 656 FormStructure* cached_submitted_form; 657 if (!FindCachedForm(form, &cached_submitted_form)) { 658 NOTREACHED(); 659 return; 660 } 661 662 // Map from field signatures to cached fields. 663 std::map<std::string, const AutoFillField*> cached_fields; 664 for (size_t i = 0; i < cached_submitted_form->field_count(); ++i) { 665 const AutoFillField* field = cached_submitted_form->field(i); 666 cached_fields[field->FieldSignature()] = field; 667 } 668 669 std::string experiment_id = cached_submitted_form->server_experiment_id(); 670 for (size_t i = 0; i < submitted_form->field_count(); ++i) { 671 const AutoFillField* field = submitted_form->field(i); 672 FieldTypeSet field_types; 673 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); 674 DCHECK(!field_types.empty()); 675 676 if (field->form_control_type() == ASCIIToUTF16("select-one")) { 677 // TODO(isherman): <select> fields don't support |is_autofilled()|. Since 678 // this is heavily relied upon by our metrics, we just don't log anything 679 // for all <select> fields. Better to have less data than misleading data. 680 continue; 681 } 682 683 // Log various quality metrics. 684 metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED, experiment_id); 685 if (field_types.find(EMPTY_TYPE) == field_types.end() && 686 field_types.find(UNKNOWN_TYPE) == field_types.end()) { 687 if (field->is_autofilled()) { 688 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED, experiment_id); 689 } else { 690 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED, 691 experiment_id); 692 693 AutoFillFieldType heuristic_type = UNKNOWN_TYPE; 694 AutoFillFieldType server_type = NO_SERVER_DATA; 695 std::map<std::string, const AutoFillField*>::const_iterator 696 cached_field = cached_fields.find(field->FieldSignature()); 697 if (cached_field != cached_fields.end()) { 698 heuristic_type = cached_field->second->heuristic_type(); 699 server_type = cached_field->second->server_type(); 700 } 701 702 if (heuristic_type == UNKNOWN_TYPE) { 703 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN, 704 experiment_id); 705 } else if (field_types.count(heuristic_type)) { 706 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH, 707 experiment_id); 708 } else { 709 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH, 710 experiment_id); 711 } 712 713 if (server_type == NO_SERVER_DATA) { 714 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN, 715 experiment_id); 716 } else if (field_types.count(server_type)) { 717 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH, 718 experiment_id); 719 } else { 720 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH, 721 experiment_id); 722 } 723 } 724 725 // TODO(isherman): Other things we might want to log here: 726 // * Per Vadim's email, a combination of (1) whether heuristics fired, 727 // (2) whether the server returned something interesting, (3) whether 728 // the user filled the field 729 // * Whether the server type matches the heursitic type 730 // - Perhaps only if at least one of the types is not unknown/no data. 731 } 732 } 733} 734 735void AutoFillManager::ImportFormData(const FormStructure& submitted_form) { 736 std::vector<const FormStructure*> import; 737 import.push_back(&submitted_form); 738 739 const CreditCard* imported_credit_card; 740 if (!personal_data_->ImportFormData(import, &imported_credit_card)) 741 return; 742 743#ifndef ANDROID 744 // If credit card information was submitted, show an infobar to offer to save 745 // it. 746 if (imported_credit_card && tab_contents_) { 747 imported_credit_card_.reset(imported_credit_card); 748 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, 749 this)); 750 } 751#endif 752} 753 754void AutoFillManager::UploadFormData(const FormStructure& submitted_form) { 755 if (!disable_download_manager_requests_) { 756 bool was_autofilled = false; 757 // Check if the form among last 3 forms that were auto-filled. 758 // Clear older signatures. 759 std::list<std::string>::iterator it; 760 int total_form_checked = 0; 761 for (it = autofilled_forms_signatures_.begin(); 762 it != autofilled_forms_signatures_.end() && total_form_checked < 3; 763 ++it, ++total_form_checked) { 764 if (*it == submitted_form.FormSignature()) 765 was_autofilled = true; 766 } 767 // Remove outdated form signatures. 768 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { 769 autofilled_forms_signatures_.erase(it, 770 autofilled_forms_signatures_.end()); 771 } 772 download_manager_.StartUploadRequest(submitted_form, was_autofilled); 773 } 774} 775 776void AutoFillManager::Reset() { 777 form_structures_.reset(); 778} 779 780void AutoFillManager::OnInfoBarClosed(bool should_save) { 781 if (should_save) 782 personal_data_->SaveImportedCreditCard(*imported_credit_card_); 783} 784 785AutoFillManager::AutoFillManager() 786 : tab_contents_(NULL), 787 personal_data_(NULL), 788 download_manager_(NULL), 789 disable_download_manager_requests_(true), 790 metric_logger_(new AutoFillMetrics), 791 cc_infobar_(NULL) { 792} 793 794AutoFillManager::AutoFillManager(TabContents* tab_contents, 795 PersonalDataManager* personal_data) 796 : tab_contents_(tab_contents), 797 personal_data_(personal_data), 798 download_manager_(NULL), 799 disable_download_manager_requests_(true), 800 metric_logger_(new AutoFillMetrics), 801 cc_infobar_(NULL) { 802 DCHECK(tab_contents); 803} 804 805void AutoFillManager::set_metric_logger( 806 const AutoFillMetrics* metric_logger) { 807 metric_logger_.reset(metric_logger); 808} 809 810bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles, 811 const std::vector<CreditCard*>& credit_cards, 812#ifdef ANDROID 813 AutoFillHost** host) { 814#else 815 RenderViewHost** host) { 816#endif 817 if (!IsAutoFillEnabled()) 818 return false; 819 820 // No autofill data to return if the profiles are empty. 821 if (profiles.empty() && credit_cards.empty()) 822 return false; 823 824#ifdef ANDROID 825 *host = tab_contents_->autofill_host(); 826#else 827 *host = tab_contents_->render_view_host(); 828#endif 829 if (!*host) 830 return false; 831 832 return true; 833} 834 835bool AutoFillManager::FindCachedForm(const FormData& form, 836 FormStructure** form_structure) { 837 // Find the FormStructure that corresponds to |form|. 838 *form_structure = NULL; 839 for (std::vector<FormStructure*>::const_iterator iter = 840 form_structures_.begin(); 841 iter != form_structures_.end(); ++iter) { 842 if (**iter == form) { 843 *form_structure = *iter; 844 break; 845 } 846 } 847 848 if (!(*form_structure)) 849 return false; 850 851 return true; 852} 853 854bool AutoFillManager::FindCachedFormAndField(const FormData& form, 855 const FormField& field, 856 FormStructure** form_structure, 857 AutoFillField** autofill_field) { 858 // Find the FormStructure that corresponds to |form|. 859 if (!FindCachedForm(form, form_structure)) 860 return false; 861 862 // No data to return if there are no auto-fillable fields. 863 if (!(*form_structure)->autofill_count()) 864 return false; 865 866 // Find the AutoFillField that corresponds to |field|. 867 *autofill_field = NULL; 868 for (std::vector<AutoFillField*>::const_iterator iter = 869 (*form_structure)->begin(); 870 iter != (*form_structure)->end(); ++iter) { 871 // The field list is terminated with a NULL AutoFillField, so don't try to 872 // dereference it. 873 if (!*iter) 874 break; 875 876 if ((**iter) == field) { 877 *autofill_field = *iter; 878 break; 879 } 880 } 881 882 if (!(*autofill_field)) 883 return false; 884 885 return true; 886} 887 888void AutoFillManager::GetProfileSuggestions(FormStructure* form, 889 const FormField& field, 890 AutoFillType type, 891 std::vector<string16>* values, 892 std::vector<string16>* labels, 893 std::vector<string16>* icons, 894 std::vector<int>* unique_ids) { 895 const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); 896 std::vector<AutoFillProfile*> matched_profiles; 897 for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); 898 iter != profiles.end(); ++iter) { 899 AutoFillProfile* profile = *iter; 900 901 // The value of the stored data for this field type in the |profile|. 902 string16 profile_field_value = profile->GetFieldText(type); 903 904 if (!profile_field_value.empty() && 905 StartsWith(profile_field_value, field.value(), false)) { 906 matched_profiles.push_back(profile); 907 values->push_back(profile_field_value); 908 unique_ids->push_back(PackGUIDs(std::string(), profile->guid())); 909 } 910 } 911 912 std::vector<AutoFillFieldType> form_fields; 913 form_fields.reserve(form->field_count()); 914 for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); 915 iter != form->end(); ++iter) { 916 // The field list is terminated with a NULL AutoFillField, so don't try to 917 // dereference it. 918 if (!*iter) 919 break; 920 form_fields.push_back((*iter)->type()); 921 } 922 923 AutoFillProfile::CreateInferredLabels(&matched_profiles, &form_fields, 924 type.field_type(), 1, labels); 925 926 // No icons for profile suggestions. 927 icons->resize(values->size()); 928} 929 930void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, 931 const FormField& field, 932 AutoFillType type, 933 std::vector<string16>* values, 934 std::vector<string16>* labels, 935 std::vector<string16>* icons, 936 std::vector<int>* unique_ids) { 937 for (std::vector<CreditCard*>::const_iterator iter = 938 personal_data_->credit_cards().begin(); 939 iter != personal_data_->credit_cards().end(); ++iter) { 940 CreditCard* credit_card = *iter; 941 942 // The value of the stored data for this field type in the |credit_card|. 943 string16 creditcard_field_value = credit_card->GetFieldText(type); 944 if (!creditcard_field_value.empty() && 945 StartsWith(creditcard_field_value, field.value(), false)) { 946 if (type.field_type() == CREDIT_CARD_NUMBER) 947 creditcard_field_value = credit_card->ObfuscatedNumber(); 948 949 values->push_back(creditcard_field_value); 950 labels->push_back(kCreditCardPrefix + credit_card->LastFourDigits()); 951 icons->push_back(credit_card->type()); 952 unique_ids->push_back(PackGUIDs(credit_card->guid(), std::string())); 953 } 954 } 955} 956 957void AutoFillManager::FillCreditCardFormField(const CreditCard* credit_card, 958 AutoFillType type, 959 webkit_glue::FormField* field) { 960 DCHECK(credit_card); 961 DCHECK(type.group() == AutoFillType::CREDIT_CARD); 962 DCHECK(field); 963 964 if (field->form_control_type() == ASCIIToUTF16("select-one")) { 965 autofill::FillSelectControl(*credit_card, type, field); 966 } else if (field->form_control_type() == ASCIIToUTF16("month")) { 967 // HTML5 input="month" consists of year-month. 968 string16 year = credit_card->GetFieldText( 969 AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR)); 970 string16 month = credit_card->GetFieldText( 971 AutoFillType(CREDIT_CARD_EXP_MONTH)); 972 if (!year.empty() && !month.empty()) { 973 // Fill the value only if |credit_card| includes both year and month 974 // information. 975 field->set_value(year + ASCIIToUTF16("-") + month); 976 } 977 } else { 978 field->set_value(credit_card->GetFieldText(type)); 979 } 980} 981 982void AutoFillManager::FillFormField(const AutoFillProfile* profile, 983 AutoFillType type, 984 webkit_glue::FormField* field) { 985 DCHECK(profile); 986 DCHECK(type.group() != AutoFillType::CREDIT_CARD); 987 DCHECK(field); 988 989 if (type.subgroup() == AutoFillType::PHONE_NUMBER) { 990 FillPhoneNumberField(profile, type, field); 991 } else { 992 if (field->form_control_type() == ASCIIToUTF16("select-one")) 993 autofill::FillSelectControl(*profile, type, field); 994 else 995 field->set_value(profile->GetFieldText(type)); 996 } 997} 998 999void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile, 1000 AutoFillType type, 1001 webkit_glue::FormField* field) { 1002 // If we are filling a phone number, check to see if the size field 1003 // matches the "prefix" or "suffix" sizes and fill accordingly. 1004 string16 number = profile->GetFieldText(AutoFillType(type)); 1005 bool has_valid_suffix_and_prefix = (number.length() == 1006 static_cast<size_t>(PhoneNumber::kPrefixLength + 1007 PhoneNumber::kSuffixLength)); 1008 if (has_valid_suffix_and_prefix && 1009 field->max_length() == PhoneNumber::kPrefixLength) { 1010 number = number.substr(PhoneNumber::kPrefixOffset, 1011 PhoneNumber::kPrefixLength); 1012 field->set_value(number); 1013 } else if (has_valid_suffix_and_prefix && 1014 field->max_length() == PhoneNumber::kSuffixLength) { 1015 number = number.substr(PhoneNumber::kSuffixOffset, 1016 PhoneNumber::kSuffixLength); 1017 field->set_value(number); 1018 } else { 1019 field->set_value(number); 1020 } 1021} 1022 1023void AutoFillManager::ParseForms(const std::vector<FormData>& forms) { 1024 std::vector<FormStructure*> non_queryable_forms; 1025 for (std::vector<FormData>::const_iterator iter = forms.begin(); 1026 iter != forms.end(); ++iter) { 1027 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); 1028 if (!form_structure->ShouldBeParsed(false)) 1029 continue; 1030 1031 // Set aside forms with method GET so that they are not included in the 1032 // query to the server. 1033 if (form_structure->ShouldBeParsed(true)) 1034 form_structures_.push_back(form_structure.release()); 1035 else 1036 non_queryable_forms.push_back(form_structure.release()); 1037 } 1038 1039 // If none of the forms were parsed, no use querying the server. 1040 if (!form_structures_.empty() && !disable_download_manager_requests_) 1041 download_manager_.StartQueryRequest(form_structures_, *metric_logger_); 1042 1043 for (std::vector<FormStructure*>::const_iterator iter = 1044 non_queryable_forms.begin(); 1045 iter != non_queryable_forms.end(); ++iter) { 1046 form_structures_.push_back(*iter); 1047 } 1048} 1049 1050// When sending IDs (across processes) to the renderer we pack credit card and 1051// profile IDs into a single integer. Credit card IDs are sent in the high 1052// word and profile IDs are sent in the low word. 1053int AutoFillManager::PackGUIDs(const std::string& cc_guid, 1054 const std::string& profile_guid) { 1055 int cc_id = GUIDToID(cc_guid); 1056 int profile_id = GUIDToID(profile_guid); 1057 1058 DCHECK(cc_id <= std::numeric_limits<unsigned short>::max()); 1059 DCHECK(profile_id <= std::numeric_limits<unsigned short>::max()); 1060 1061 return cc_id << std::numeric_limits<unsigned short>::digits | profile_id; 1062} 1063 1064// When receiving IDs (across processes) from the renderer we unpack credit card 1065// and profile IDs from a single integer. Credit card IDs are stored in the 1066// high word and profile IDs are stored in the low word. 1067void AutoFillManager::UnpackGUIDs(int id, 1068 std::string* cc_guid, 1069 std::string* profile_guid) { 1070 int cc_id = id >> std::numeric_limits<unsigned short>::digits & 1071 std::numeric_limits<unsigned short>::max(); 1072 int profile_id = id & std::numeric_limits<unsigned short>::max(); 1073 1074 *cc_guid = IDToGUID(cc_id); 1075 *profile_guid = IDToGUID(profile_id); 1076} 1077 1078int AutoFillManager::GUIDToID(const std::string& guid) { 1079 static int last_id = 1; 1080 1081 if (!guid::IsValidGUID(guid)) 1082 return 0; 1083 1084 std::map<std::string, int>::const_iterator iter = guid_id_map_.find(guid); 1085 if (iter == guid_id_map_.end()) { 1086 guid_id_map_[guid] = last_id; 1087 id_guid_map_[last_id] = guid; 1088 return last_id++; 1089 } else { 1090 return iter->second; 1091 } 1092} 1093 1094const std::string AutoFillManager::IDToGUID(int id) { 1095 if (id == 0) 1096 return std::string(); 1097 1098 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); 1099 if (iter == id_guid_map_.end()) { 1100 NOTREACHED(); 1101 return std::string(); 1102 } 1103 1104 return iter->second; 1105} 1106