Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/autofill/core/browser/autofill_manager.h" | 5 #include "components/autofill/core/browser/autofill_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 #include "components/autofill/core/common/form_field_data.h" | 44 #include "components/autofill/core/common/form_field_data.h" |
| 45 #include "components/autofill/core/common/password_form_fill_data.h" | 45 #include "components/autofill/core/common/password_form_fill_data.h" |
| 46 #include "components/pref_registry/pref_registry_syncable.h" | 46 #include "components/pref_registry/pref_registry_syncable.h" |
| 47 #include "grit/components_strings.h" | 47 #include "grit/components_strings.h" |
| 48 #include "ui/base/l10n/l10n_util.h" | 48 #include "ui/base/l10n/l10n_util.h" |
| 49 #include "ui/gfx/rect.h" | 49 #include "ui/gfx/rect.h" |
| 50 #include "url/gurl.h" | 50 #include "url/gurl.h" |
| 51 | 51 |
| 52 namespace autofill { | 52 namespace autofill { |
| 53 | 53 |
| 54 typedef PersonalDataManager::GUIDPair GUIDPair; | |
| 55 | |
| 56 using base::TimeTicks; | 54 using base::TimeTicks; |
| 57 | 55 |
| 58 namespace { | 56 namespace { |
| 59 | 57 |
| 60 // We only send a fraction of the forms to upload server. | 58 // We only send a fraction of the forms to upload server. |
| 61 // The rate for positive/negative matches potentially could be different. | 59 // The rate for positive/negative matches potentially could be different. |
| 62 const double kAutofillPositiveUploadRateDefaultValue = 0.20; | 60 const double kAutofillPositiveUploadRateDefaultValue = 0.20; |
| 63 const double kAutofillNegativeUploadRateDefaultValue = 0.20; | 61 const double kAutofillNegativeUploadRateDefaultValue = 0.20; |
| 64 | 62 |
| 65 const size_t kMaxRecentFormSignaturesToRemember = 3; | 63 const size_t kMaxRecentFormSignaturesToRemember = 3; |
| 66 | 64 |
| 67 // Set a conservative upper bound on the number of forms we are willing to | 65 // Set a conservative upper bound on the number of forms we are willing to |
| 68 // cache, simply to prevent unbounded memory consumption. | 66 // cache, simply to prevent unbounded memory consumption. |
| 69 const size_t kMaxFormCacheSize = 100; | 67 const size_t kMaxFormCacheSize = 100; |
| 70 | 68 |
| 71 // Removes duplicate suggestions whilst preserving their original order. | 69 // Removes duplicate suggestions whilst preserving their original order. |
| 72 void RemoveDuplicateSuggestions(std::vector<base::string16>* values, | 70 void RemoveDuplicateSuggestions(std::vector<Suggestion>* suggestions) { |
| 73 std::vector<base::string16>* labels, | 71 std::set<std::pair<base::string16, base::string16>> seen_suggestions; |
|
Evan Stade
2014/12/10 23:11:14
I think you need > >
brettw
2014/12/12 00:44:14
This is legal now with C++11.
| |
| 74 std::vector<base::string16>* icons, | |
| 75 std::vector<int>* unique_ids) { | |
| 76 DCHECK_EQ(values->size(), labels->size()); | |
| 77 DCHECK_EQ(values->size(), icons->size()); | |
| 78 DCHECK_EQ(values->size(), unique_ids->size()); | |
| 79 | 72 |
| 80 std::set<std::pair<base::string16, base::string16> > seen_suggestions; | 73 for (int i = 0; i < static_cast<int>(suggestions->size()); ++i) { |
| 81 std::vector<base::string16> values_copy; | 74 if (!seen_suggestions.insert(std::make_pair( |
| 82 std::vector<base::string16> labels_copy; | 75 (*suggestions)[i].value, (*suggestions)[i].label)).second) { |
| 83 std::vector<base::string16> icons_copy; | 76 // Duplicate found, delete it. |
| 84 std::vector<int> unique_ids_copy; | 77 suggestions->erase(suggestions->begin() + i); |
| 85 | 78 i--; |
| 86 for (size_t i = 0; i < values->size(); ++i) { | |
| 87 const std::pair<base::string16, base::string16> suggestion( | |
| 88 (*values)[i], (*labels)[i]); | |
| 89 if (seen_suggestions.insert(suggestion).second) { | |
| 90 values_copy.push_back((*values)[i]); | |
| 91 labels_copy.push_back((*labels)[i]); | |
| 92 icons_copy.push_back((*icons)[i]); | |
| 93 unique_ids_copy.push_back((*unique_ids)[i]); | |
| 94 } | 79 } |
| 95 } | 80 } |
| 96 | |
| 97 values->swap(values_copy); | |
| 98 labels->swap(labels_copy); | |
| 99 icons->swap(icons_copy); | |
| 100 unique_ids->swap(unique_ids_copy); | |
| 101 } | 81 } |
| 102 | 82 |
| 103 // Precondition: |form_structure| and |form| should correspond to the same | 83 // Precondition: |form_structure| and |form| should correspond to the same |
| 104 // logical form. Returns true if any field in the given |section| within |form| | 84 // logical form. Returns true if any field in the given |section| within |form| |
| 105 // is auto-filled. | 85 // is auto-filled. |
| 106 bool SectionIsAutofilled(const FormStructure& form_structure, | 86 bool SectionIsAutofilled(const FormStructure& form_structure, |
| 107 const FormData& form, | 87 const FormData& form, |
| 108 const std::string& section) { | 88 const std::string& section) { |
| 109 DCHECK_EQ(form_structure.field_count(), form.fields.size()); | 89 DCHECK_EQ(form_structure.field_count(), form.fields.size()); |
| 110 for (size_t i = 0; i < form_structure.field_count(); ++i) { | 90 for (size_t i = 0; i < form_structure.field_count(); ++i) { |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 } | 430 } |
| 451 | 431 |
| 452 void AutofillManager::OnQueryFormFieldAutofill(int query_id, | 432 void AutofillManager::OnQueryFormFieldAutofill(int query_id, |
| 453 const FormData& form, | 433 const FormData& form, |
| 454 const FormFieldData& field, | 434 const FormFieldData& field, |
| 455 const gfx::RectF& bounding_box, | 435 const gfx::RectF& bounding_box, |
| 456 bool display_warning) { | 436 bool display_warning) { |
| 457 if (!IsValidFormData(form) || !IsValidFormFieldData(field)) | 437 if (!IsValidFormData(form) || !IsValidFormFieldData(field)) |
| 458 return; | 438 return; |
| 459 | 439 |
| 460 std::vector<base::string16> values; | 440 std::vector<Suggestion> suggestions; |
| 461 std::vector<base::string16> labels; | |
| 462 std::vector<base::string16> icons; | |
| 463 std::vector<int> unique_ids; | |
| 464 | 441 |
| 465 external_delegate_->OnQuery(query_id, | 442 external_delegate_->OnQuery(query_id, |
| 466 form, | 443 form, |
| 467 field, | 444 field, |
| 468 bounding_box, | 445 bounding_box, |
| 469 display_warning); | 446 display_warning); |
| 470 FormStructure* form_structure = NULL; | 447 FormStructure* form_structure = NULL; |
| 471 AutofillField* autofill_field = NULL; | 448 AutofillField* autofill_field = NULL; |
| 472 if (RefreshDataModels() && | 449 if (RefreshDataModels() && |
| 473 driver_->RendererIsAvailable() && | 450 driver_->RendererIsAvailable() && |
| 474 GetCachedFormAndField(form, field, &form_structure, &autofill_field) && | 451 GetCachedFormAndField(form, field, &form_structure, &autofill_field) && |
| 475 // Don't send suggestions for forms that aren't auto-fillable. | 452 // Don't send suggestions for forms that aren't auto-fillable. |
| 476 form_structure->IsAutofillable()) { | 453 form_structure->IsAutofillable()) { |
| 477 AutofillType type = autofill_field->Type(); | 454 AutofillType type = autofill_field->Type(); |
| 478 bool is_filling_credit_card = (type.group() == CREDIT_CARD); | 455 bool is_filling_credit_card = (type.group() == CREDIT_CARD); |
| 479 if (is_filling_credit_card) { | 456 if (is_filling_credit_card) { |
| 480 GetCreditCardSuggestions( | 457 GetCreditCardSuggestions(field, type, &suggestions); |
| 481 field, type, &values, &labels, &icons, &unique_ids); | |
| 482 } else { | 458 } else { |
| 483 GetProfileSuggestions(*form_structure, | 459 GetProfileSuggestions(*form_structure, field, *autofill_field, |
| 484 field, | 460 &suggestions); |
| 485 *autofill_field, | |
| 486 &values, | |
| 487 &labels, | |
| 488 &icons, | |
| 489 &unique_ids); | |
| 490 } | 461 } |
| 491 | 462 |
| 492 DCHECK_EQ(values.size(), labels.size()); | 463 if (!suggestions.empty()) { |
| 493 DCHECK_EQ(values.size(), icons.size()); | |
| 494 DCHECK_EQ(values.size(), unique_ids.size()); | |
| 495 | |
| 496 if (!values.empty()) { | |
| 497 // Don't provide Autofill suggestions when Autofill is disabled, and don't | 464 // Don't provide Autofill suggestions when Autofill is disabled, and don't |
| 498 // provide credit card suggestions for non-HTTPS pages. However, provide a | 465 // provide credit card suggestions for non-HTTPS pages. However, provide a |
| 499 // warning to the user in these cases. | 466 // warning to the user in these cases. |
| 500 int warning = 0; | 467 int warning = 0; |
| 501 if (is_filling_credit_card && !FormIsHTTPS(*form_structure)) { | 468 if (is_filling_credit_card && !FormIsHTTPS(*form_structure)) { |
| 502 warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION; | 469 warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION; |
| 503 } | 470 } |
| 504 if (warning) { | 471 if (warning) { |
| 505 values.assign(1, l10n_util::GetStringUTF16(warning)); | 472 Suggestion warning_suggestion(l10n_util::GetStringUTF16(warning)); |
| 506 labels.assign(1, base::string16()); | 473 warning_suggestion.frontend_id = POPUP_ITEM_ID_WARNING_MESSAGE; |
| 507 icons.assign(1, base::string16()); | 474 suggestions.assign(1, warning_suggestion); |
| 508 unique_ids.assign(1, POPUP_ITEM_ID_WARNING_MESSAGE); | |
| 509 } else { | 475 } else { |
| 510 bool section_is_autofilled = | 476 bool section_is_autofilled = |
| 511 SectionIsAutofilled(*form_structure, form, | 477 SectionIsAutofilled(*form_structure, form, |
| 512 autofill_field->section()); | 478 autofill_field->section()); |
| 513 if (section_is_autofilled) { | 479 if (section_is_autofilled) { |
| 514 // If the relevant section is auto-filled and the renderer is querying | 480 // If the relevant section is auto-filled and the renderer is querying |
| 515 // for suggestions, then the user is editing the value of a field. | 481 // for suggestions, then the user is editing the value of a field. |
| 516 // In this case, mimic autocomplete: don't display labels or icons, | 482 // In this case, mimic autocomplete: don't display labels or icons, |
| 517 // as that information is redundant. | 483 // as that information is redundant. |
| 518 labels.assign(labels.size(), base::string16()); | 484 for (size_t i = 0; i < suggestions.size(); i++) { |
| 519 icons.assign(icons.size(), base::string16()); | 485 suggestions[i].label = base::string16(); |
| 486 suggestions[i].icon = base::string16(); | |
| 487 } | |
| 520 } | 488 } |
| 521 | 489 |
| 522 // When filling credit card suggestions, the values and labels are | 490 // When filling credit card suggestions, the values and labels are |
| 523 // typically obfuscated, which makes detecting duplicates hard. Since | 491 // typically obfuscated, which makes detecting duplicates hard. Since |
| 524 // duplicates only tend to be a problem when filling address forms | 492 // duplicates only tend to be a problem when filling address forms |
| 525 // anyway, only don't de-dup credit card suggestions. | 493 // anyway, only don't de-dup credit card suggestions. |
| 526 if (!is_filling_credit_card) | 494 if (!is_filling_credit_card) |
| 527 RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids); | 495 RemoveDuplicateSuggestions(&suggestions); |
| 528 | 496 |
| 529 // The first time we show suggestions on this page, log the number of | 497 // The first time we show suggestions on this page, log the number of |
| 530 // suggestions shown. | 498 // suggestions shown. |
| 531 if (!has_logged_address_suggestions_count_ && !section_is_autofilled) { | 499 if (!has_logged_address_suggestions_count_ && !section_is_autofilled) { |
| 532 metric_logger_->LogAddressSuggestionsCount(values.size()); | 500 metric_logger_->LogAddressSuggestionsCount(suggestions.size()); |
| 533 has_logged_address_suggestions_count_ = true; | 501 has_logged_address_suggestions_count_ = true; |
| 534 } | 502 } |
| 535 } | 503 } |
| 536 } | 504 } |
| 537 } | 505 } |
| 538 | 506 |
| 539 if (field.should_autocomplete) { | 507 if (field.should_autocomplete) { |
| 540 // Add the results from AutoComplete. They come back asynchronously, so we | 508 // Add the results from AutoComplete. They come back asynchronously, so we |
| 541 // hand off what we generated and they will send the results back to the | 509 // hand off what we generated and they will send the results back to the |
| 542 // renderer. | 510 // renderer. |
| 543 autocomplete_history_manager_->OnGetAutocompleteSuggestions( | 511 autocomplete_history_manager_->OnGetAutocompleteSuggestions( |
| 544 query_id, field.name, field.value, field.form_control_type, values, | 512 query_id, field.name, field.value, field.form_control_type, |
| 545 labels, icons, unique_ids); | 513 suggestions); |
| 546 } else { | 514 } else { |
| 547 // Autocomplete is disabled for this field; only pass back Autofill | 515 // Autocomplete is disabled for this field; only pass back Autofill |
| 548 // suggestions. | 516 // suggestions. |
| 549 autocomplete_history_manager_->CancelPendingQuery(); | 517 autocomplete_history_manager_->CancelPendingQuery(); |
| 550 external_delegate_->OnSuggestionsReturned( | 518 external_delegate_->OnSuggestionsReturned( |
| 551 query_id, values, labels, icons, unique_ids); | 519 query_id, suggestions); |
| 552 } | 520 } |
| 553 } | 521 } |
| 554 | 522 |
| 555 void AutofillManager::FillOrPreviewForm( | 523 void AutofillManager::FillOrPreviewForm( |
| 556 AutofillDriver::RendererFormDataAction action, | 524 AutofillDriver::RendererFormDataAction action, |
| 557 int query_id, | 525 int query_id, |
| 558 const FormData& form, | 526 const FormData& form, |
| 559 const FormFieldData& field, | 527 const FormFieldData& field, |
| 560 int unique_id) { | 528 int unique_id) { |
| 561 if (!IsValidFormData(form) || !IsValidFormFieldData(field)) | 529 if (!IsValidFormData(form) || !IsValidFormFieldData(field)) |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 851 | 819 |
| 852 return true; | 820 return true; |
| 853 } | 821 } |
| 854 | 822 |
| 855 bool AutofillManager::GetProfileOrCreditCard( | 823 bool AutofillManager::GetProfileOrCreditCard( |
| 856 int unique_id, | 824 int unique_id, |
| 857 const AutofillDataModel** data_model, | 825 const AutofillDataModel** data_model, |
| 858 size_t* variant, | 826 size_t* variant, |
| 859 bool* is_credit_card) const { | 827 bool* is_credit_card) const { |
| 860 // Unpack the |unique_id| into component parts. | 828 // Unpack the |unique_id| into component parts. |
| 861 GUIDPair credit_card_guid; | 829 SuggestionBackendID credit_card_id; |
| 862 GUIDPair profile_guid; | 830 SuggestionBackendID profile_id; |
| 863 UnpackGUIDs(unique_id, &credit_card_guid, &profile_guid); | 831 SplitFrontendID(unique_id, &credit_card_id, &profile_id); |
| 864 DCHECK(!base::IsValidGUID(credit_card_guid.first) || | 832 DCHECK(!base::IsValidGUID(credit_card_id.guid) || |
| 865 !base::IsValidGUID(profile_guid.first)); | 833 !base::IsValidGUID(profile_id.guid)); |
| 866 *is_credit_card = false; | 834 *is_credit_card = false; |
| 867 | 835 |
| 868 // Find the profile that matches the |profile_guid|, if one is specified. | 836 // Find the profile that matches the |profile_guid|, if one is specified. |
| 869 // Otherwise find the credit card that matches the |credit_card_guid|, | 837 // Otherwise find the credit card that matches the |credit_card_guid|, |
| 870 // if specified. | 838 // if specified. |
| 871 if (base::IsValidGUID(profile_guid.first)) { | 839 if (base::IsValidGUID(profile_id.guid)) { |
| 872 *data_model = personal_data_->GetProfileByGUID(profile_guid.first); | 840 *data_model = personal_data_->GetProfileByGUID(profile_id.guid); |
| 873 *variant = profile_guid.second; | 841 *variant = profile_id.variant; |
| 874 } else if (base::IsValidGUID(credit_card_guid.first)) { | 842 } else if (base::IsValidGUID(credit_card_id.guid)) { |
| 875 *data_model = personal_data_->GetCreditCardByGUID(credit_card_guid.first); | 843 *data_model = personal_data_->GetCreditCardByGUID(credit_card_id.guid); |
| 876 *variant = credit_card_guid.second; | 844 *variant = credit_card_id.variant; |
| 877 *is_credit_card = true; | 845 *is_credit_card = true; |
| 878 } | 846 } |
| 879 | 847 |
| 880 return !!*data_model; | 848 return !!*data_model; |
| 881 } | 849 } |
| 882 | 850 |
| 883 void AutofillManager::FillOrPreviewDataModelForm( | 851 void AutofillManager::FillOrPreviewDataModelForm( |
| 884 AutofillDriver::RendererFormDataAction action, | 852 AutofillDriver::RendererFormDataAction action, |
| 885 int query_id, | 853 int query_id, |
| 886 const FormData& form, | 854 const FormData& form, |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 std::vector<FormStructure*> forms(1, *updated_form); | 1101 std::vector<FormStructure*> forms(1, *updated_form); |
| 1134 driver_->SendAutofillTypePredictionsToRenderer(forms); | 1102 driver_->SendAutofillTypePredictionsToRenderer(forms); |
| 1135 | 1103 |
| 1136 return true; | 1104 return true; |
| 1137 } | 1105 } |
| 1138 | 1106 |
| 1139 void AutofillManager::GetProfileSuggestions( | 1107 void AutofillManager::GetProfileSuggestions( |
| 1140 const FormStructure& form, | 1108 const FormStructure& form, |
| 1141 const FormFieldData& field, | 1109 const FormFieldData& field, |
| 1142 const AutofillField& autofill_field, | 1110 const AutofillField& autofill_field, |
| 1143 std::vector<base::string16>* values, | 1111 std::vector<Suggestion>* suggestions) const { |
| 1144 std::vector<base::string16>* labels, | |
| 1145 std::vector<base::string16>* icons, | |
| 1146 std::vector<int>* unique_ids) const { | |
| 1147 std::vector<ServerFieldType> field_types(form.field_count()); | 1112 std::vector<ServerFieldType> field_types(form.field_count()); |
| 1148 for (size_t i = 0; i < form.field_count(); ++i) { | 1113 for (size_t i = 0; i < form.field_count(); ++i) { |
| 1149 field_types.push_back(form.field(i)->Type().GetStorableType()); | 1114 field_types.push_back(form.field(i)->Type().GetStorableType()); |
| 1150 } | 1115 } |
| 1151 std::vector<GUIDPair> guid_pairs; | |
| 1152 | 1116 |
| 1153 personal_data_->GetProfileSuggestions( | 1117 personal_data_->GetProfileSuggestions( |
| 1154 autofill_field.Type(), field.value, field.is_autofilled, field_types, | 1118 autofill_field.Type(), field.value, field.is_autofilled, field_types, |
| 1155 base::Callback<bool(const AutofillProfile&)>(), | 1119 base::Callback<bool(const AutofillProfile&)>(), suggestions); |
| 1156 values, labels, icons, &guid_pairs); | |
| 1157 | 1120 |
| 1158 // Adjust phone number to display in prefix/suffix case. | 1121 // Adjust phone number to display in prefix/suffix case. |
| 1159 if (autofill_field.Type().GetStorableType() == PHONE_HOME_NUMBER) { | 1122 if (autofill_field.Type().GetStorableType() == PHONE_HOME_NUMBER) { |
| 1160 for (size_t i = 0; i < values->size(); ++i) { | 1123 for (size_t i = 0; i < suggestions->size(); ++i) { |
| 1161 (*values)[i] = AutofillField::GetPhoneNumberValue( | 1124 (*suggestions)[i].value = AutofillField::GetPhoneNumberValue( |
| 1162 autofill_field, (*values)[i], field); | 1125 autofill_field, (*suggestions)[i].value, field); |
| 1163 } | 1126 } |
| 1164 } | 1127 } |
| 1165 | 1128 |
| 1166 for (size_t i = 0; i < guid_pairs.size(); ++i) { | 1129 for (size_t i = 0; i < suggestions->size(); ++i) { |
| 1167 unique_ids->push_back(PackGUIDs(GUIDPair(std::string(), 0), | 1130 (*suggestions)[i].frontend_id = |
| 1168 guid_pairs[i])); | 1131 MakeFrontendID(SuggestionBackendID(), (*suggestions)[i].backend_id); |
| 1169 } | 1132 } |
| 1170 } | 1133 } |
| 1171 | 1134 |
| 1172 void AutofillManager::GetCreditCardSuggestions( | 1135 void AutofillManager::GetCreditCardSuggestions( |
| 1173 const FormFieldData& field, | 1136 const FormFieldData& field, |
| 1174 const AutofillType& type, | 1137 const AutofillType& type, |
| 1175 std::vector<base::string16>* values, | 1138 std::vector<Suggestion>* suggestions) const { |
| 1176 std::vector<base::string16>* labels, | 1139 personal_data_->GetCreditCardSuggestions(type, field.value, suggestions); |
| 1177 std::vector<base::string16>* icons, | 1140 for (size_t i = 0; i < suggestions->size(); i++) { |
| 1178 std::vector<int>* unique_ids) const { | 1141 (*suggestions)[i].frontend_id = |
| 1179 std::vector<GUIDPair> guid_pairs; | 1142 MakeFrontendID((*suggestions)[i].backend_id, SuggestionBackendID()); |
| 1180 personal_data_->GetCreditCardSuggestions( | |
| 1181 type, field.value, values, labels, icons, &guid_pairs); | |
| 1182 | |
| 1183 for (size_t i = 0; i < guid_pairs.size(); ++i) { | |
| 1184 unique_ids->push_back(PackGUIDs(guid_pairs[i], GUIDPair(std::string(), 0))); | |
| 1185 } | 1143 } |
| 1186 } | 1144 } |
| 1187 | 1145 |
| 1188 void AutofillManager::ParseForms(const std::vector<FormData>& forms) { | 1146 void AutofillManager::ParseForms(const std::vector<FormData>& forms) { |
| 1189 std::vector<FormStructure*> non_queryable_forms; | 1147 std::vector<FormStructure*> non_queryable_forms; |
| 1190 for (std::vector<FormData>::const_iterator iter = forms.begin(); | 1148 for (std::vector<FormData>::const_iterator iter = forms.begin(); |
| 1191 iter != forms.end(); ++iter) { | 1149 iter != forms.end(); ++iter) { |
| 1192 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); | 1150 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); |
| 1193 if (!form_structure->ShouldBeParsed()) | 1151 if (!form_structure->ShouldBeParsed()) |
| 1194 continue; | 1152 continue; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1215 | 1173 |
| 1216 if (!form_structures_.empty()) | 1174 if (!form_structures_.empty()) |
| 1217 metric_logger_->LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED); | 1175 metric_logger_->LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED); |
| 1218 | 1176 |
| 1219 // For the |non_queryable_forms|, we have all the field type info we're ever | 1177 // For the |non_queryable_forms|, we have all the field type info we're ever |
| 1220 // going to get about them. For the other forms, we'll wait until we get a | 1178 // going to get about them. For the other forms, we'll wait until we get a |
| 1221 // response from the server. | 1179 // response from the server. |
| 1222 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms); | 1180 driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms); |
| 1223 } | 1181 } |
| 1224 | 1182 |
| 1225 int AutofillManager::GUIDToID(const GUIDPair& guid) const { | 1183 int AutofillManager::BackendIDToInt( |
| 1226 if (!base::IsValidGUID(guid.first)) | 1184 const SuggestionBackendID& backend_id) const { |
| 1185 if (!base::IsValidGUID(backend_id.guid)) | |
| 1227 return 0; | 1186 return 0; |
| 1228 | 1187 |
| 1229 std::map<GUIDPair, int>::const_iterator iter = guid_id_map_.find(guid); | 1188 const auto found = backend_to_int_map_.find(backend_id); |
| 1230 if (iter == guid_id_map_.end()) { | 1189 if (found == backend_to_int_map_.end()) { |
| 1231 int id = guid_id_map_.size() + 1; | 1190 // Unknown one, make a new entry. |
| 1232 guid_id_map_[guid] = id; | 1191 int int_id = backend_to_int_map_.size() + 1; |
| 1233 id_guid_map_[id] = guid; | 1192 backend_to_int_map_[backend_id] = int_id; |
| 1234 return id; | 1193 int_to_backend_map_[int_id] = backend_id; |
| 1235 } else { | 1194 return int_id; |
| 1236 return iter->second; | |
| 1237 } | 1195 } |
| 1196 return found->second; | |
| 1238 } | 1197 } |
| 1239 | 1198 |
| 1240 const GUIDPair AutofillManager::IDToGUID(int id) const { | 1199 SuggestionBackendID AutofillManager::IntToBackendID(int int_id) const { |
| 1241 if (id == 0) | 1200 if (int_id == 0) |
| 1242 return GUIDPair(std::string(), 0); | 1201 return SuggestionBackendID(); |
| 1243 | 1202 |
| 1244 std::map<int, GUIDPair>::const_iterator iter = id_guid_map_.find(id); | 1203 const auto found = int_to_backend_map_.find(int_id); |
| 1245 if (iter == id_guid_map_.end()) { | 1204 if (found == int_to_backend_map_.end()) { |
| 1246 NOTREACHED(); | 1205 NOTREACHED(); |
| 1247 return GUIDPair(std::string(), 0); | 1206 return SuggestionBackendID(); |
| 1248 } | 1207 } |
| 1249 | 1208 return found->second; |
| 1250 return iter->second; | |
| 1251 } | 1209 } |
| 1252 | 1210 |
| 1253 // When sending IDs (across processes) to the renderer we pack credit card and | 1211 // When sending IDs (across processes) to the renderer we pack credit card and |
| 1254 // profile IDs into a single integer. Credit card IDs are sent in the high | 1212 // profile IDs into a single integer. Credit card IDs are sent in the high |
| 1255 // word and profile IDs are sent in the low word. | 1213 // word and profile IDs are sent in the low word. |
| 1256 int AutofillManager::PackGUIDs(const GUIDPair& cc_guid, | 1214 int AutofillManager::MakeFrontendID( |
| 1257 const GUIDPair& profile_guid) const { | 1215 const SuggestionBackendID& cc_backend_id, |
| 1258 int cc_id = GUIDToID(cc_guid); | 1216 const SuggestionBackendID& profile_backend_id) const { |
| 1259 int profile_id = GUIDToID(profile_guid); | 1217 int cc_int_id = BackendIDToInt(cc_backend_id); |
| 1218 int profile_int_id = BackendIDToInt(profile_backend_id); | |
| 1260 | 1219 |
| 1261 DCHECK(cc_id <= std::numeric_limits<unsigned short>::max()); | 1220 // Should fit in signed 16-bit integers. We use 16-bits each when combining |
| 1262 DCHECK(profile_id <= std::numeric_limits<unsigned short>::max()); | 1221 // below, and negative frontend IDs have special meaning so we can never use |
| 1222 // the high bit. | |
| 1223 DCHECK(cc_int_id <= std::numeric_limits<int16_t>::max()); | |
| 1224 DCHECK(profile_int_id <= std::numeric_limits<int16_t>::max()); | |
| 1263 | 1225 |
| 1264 return cc_id << std::numeric_limits<unsigned short>::digits | profile_id; | 1226 // Put CC in the high half of the bits. |
| 1227 return (cc_int_id << std::numeric_limits<uint16_t>::digits) | profile_int_id; | |
| 1265 } | 1228 } |
| 1266 | 1229 |
| 1267 // When receiving IDs (across processes) from the renderer we unpack credit card | 1230 // When receiving IDs (across processes) from the renderer we unpack credit card |
| 1268 // and profile IDs from a single integer. Credit card IDs are stored in the | 1231 // and profile IDs from a single integer. Credit card IDs are stored in the |
| 1269 // high word and profile IDs are stored in the low word. | 1232 // high word and profile IDs are stored in the low word. |
| 1270 void AutofillManager::UnpackGUIDs(int id, | 1233 void AutofillManager::SplitFrontendID( |
| 1271 GUIDPair* cc_guid, | 1234 int frontend_id, |
| 1272 GUIDPair* profile_guid) const { | 1235 SuggestionBackendID* cc_backend_id, |
| 1273 int cc_id = id >> std::numeric_limits<unsigned short>::digits & | 1236 SuggestionBackendID* profile_backend_id) const { |
| 1274 std::numeric_limits<unsigned short>::max(); | 1237 int cc_int_id = (frontend_id >> std::numeric_limits<uint16_t>::digits) & |
| 1275 int profile_id = id & std::numeric_limits<unsigned short>::max(); | 1238 std::numeric_limits<uint16_t>::max(); |
| 1239 int profile_int_id = frontend_id & std::numeric_limits<uint16_t>::max(); | |
| 1276 | 1240 |
| 1277 *cc_guid = IDToGUID(cc_id); | 1241 *cc_backend_id = IntToBackendID(cc_int_id); |
| 1278 *profile_guid = IDToGUID(profile_id); | 1242 *profile_backend_id = IntToBackendID(profile_int_id); |
| 1279 } | 1243 } |
| 1280 | 1244 |
| 1281 void AutofillManager::UpdateInitialInteractionTimestamp( | 1245 void AutofillManager::UpdateInitialInteractionTimestamp( |
| 1282 const TimeTicks& interaction_timestamp) { | 1246 const TimeTicks& interaction_timestamp) { |
| 1283 if (initial_interaction_timestamp_.is_null() || | 1247 if (initial_interaction_timestamp_.is_null() || |
| 1284 interaction_timestamp < initial_interaction_timestamp_) { | 1248 interaction_timestamp < initial_interaction_timestamp_) { |
| 1285 initial_interaction_timestamp_ = interaction_timestamp; | 1249 initial_interaction_timestamp_ = interaction_timestamp; |
| 1286 } | 1250 } |
| 1287 } | 1251 } |
| 1288 | 1252 |
| 1289 bool AutofillManager::ShouldUploadForm(const FormStructure& form) { | 1253 bool AutofillManager::ShouldUploadForm(const FormStructure& form) { |
| 1290 if (!IsAutofillEnabled()) | 1254 if (!IsAutofillEnabled()) |
| 1291 return false; | 1255 return false; |
| 1292 | 1256 |
| 1293 if (driver_->IsOffTheRecord()) | 1257 if (driver_->IsOffTheRecord()) |
| 1294 return false; | 1258 return false; |
| 1295 | 1259 |
| 1296 // Disregard forms that we wouldn't ever autofill in the first place. | 1260 // Disregard forms that we wouldn't ever autofill in the first place. |
| 1297 if (!form.ShouldBeParsed()) | 1261 if (!form.ShouldBeParsed()) |
| 1298 return false; | 1262 return false; |
| 1299 | 1263 |
| 1300 return true; | 1264 return true; |
| 1301 } | 1265 } |
| 1302 | 1266 |
| 1303 } // namespace autofill | 1267 } // namespace autofill |
| OLD | NEW |