| Index: components/autofill/core/browser/autofill_manager.cc
|
| diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
|
| index 2032879adef8e2d070a08d029b8bb295ceca5798..ebb899bf4ab4dcb7de676f9201676c58089b619c 100644
|
| --- a/components/autofill/core/browser/autofill_manager.cc
|
| +++ b/components/autofill/core/browser/autofill_manager.cc
|
| @@ -51,8 +51,6 @@
|
|
|
| namespace autofill {
|
|
|
| -typedef PersonalDataManager::GUIDPair GUIDPair;
|
| -
|
| using base::TimeTicks;
|
|
|
| namespace {
|
| @@ -69,35 +67,17 @@ const size_t kMaxRecentFormSignaturesToRemember = 3;
|
| const size_t kMaxFormCacheSize = 100;
|
|
|
| // Removes duplicate suggestions whilst preserving their original order.
|
| -void RemoveDuplicateSuggestions(std::vector<base::string16>* values,
|
| - std::vector<base::string16>* labels,
|
| - std::vector<base::string16>* icons,
|
| - std::vector<int>* unique_ids) {
|
| - DCHECK_EQ(values->size(), labels->size());
|
| - DCHECK_EQ(values->size(), icons->size());
|
| - DCHECK_EQ(values->size(), unique_ids->size());
|
| -
|
| - std::set<std::pair<base::string16, base::string16> > seen_suggestions;
|
| - std::vector<base::string16> values_copy;
|
| - std::vector<base::string16> labels_copy;
|
| - std::vector<base::string16> icons_copy;
|
| - std::vector<int> unique_ids_copy;
|
| -
|
| - for (size_t i = 0; i < values->size(); ++i) {
|
| - const std::pair<base::string16, base::string16> suggestion(
|
| - (*values)[i], (*labels)[i]);
|
| - if (seen_suggestions.insert(suggestion).second) {
|
| - values_copy.push_back((*values)[i]);
|
| - labels_copy.push_back((*labels)[i]);
|
| - icons_copy.push_back((*icons)[i]);
|
| - unique_ids_copy.push_back((*unique_ids)[i]);
|
| +void RemoveDuplicateSuggestions(std::vector<Suggestion>* suggestions) {
|
| + std::set<std::pair<base::string16, base::string16>> seen_suggestions;
|
| +
|
| + for (int i = 0; i < static_cast<int>(suggestions->size()); ++i) {
|
| + if (!seen_suggestions.insert(std::make_pair(
|
| + (*suggestions)[i].value, (*suggestions)[i].label)).second) {
|
| + // Duplicate found, delete it.
|
| + suggestions->erase(suggestions->begin() + i);
|
| + i--;
|
| }
|
| }
|
| -
|
| - values->swap(values_copy);
|
| - labels->swap(labels_copy);
|
| - icons->swap(icons_copy);
|
| - unique_ids->swap(unique_ids_copy);
|
| }
|
|
|
| // Precondition: |form_structure| and |form| should correspond to the same
|
| @@ -457,10 +437,7 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
|
| if (!IsValidFormData(form) || !IsValidFormFieldData(field))
|
| return;
|
|
|
| - std::vector<base::string16> values;
|
| - std::vector<base::string16> labels;
|
| - std::vector<base::string16> icons;
|
| - std::vector<int> unique_ids;
|
| + std::vector<Suggestion> suggestions;
|
|
|
| external_delegate_->OnQuery(query_id,
|
| form,
|
| @@ -477,23 +454,13 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
|
| AutofillType type = autofill_field->Type();
|
| bool is_filling_credit_card = (type.group() == CREDIT_CARD);
|
| if (is_filling_credit_card) {
|
| - GetCreditCardSuggestions(
|
| - field, type, &values, &labels, &icons, &unique_ids);
|
| + suggestions = GetCreditCardSuggestions(field, type);
|
| } else {
|
| - GetProfileSuggestions(*form_structure,
|
| - field,
|
| - *autofill_field,
|
| - &values,
|
| - &labels,
|
| - &icons,
|
| - &unique_ids);
|
| + suggestions =
|
| + GetProfileSuggestions(*form_structure, field, *autofill_field);
|
| }
|
|
|
| - DCHECK_EQ(values.size(), labels.size());
|
| - DCHECK_EQ(values.size(), icons.size());
|
| - DCHECK_EQ(values.size(), unique_ids.size());
|
| -
|
| - if (!values.empty()) {
|
| + if (!suggestions.empty()) {
|
| // Don't provide Autofill suggestions when Autofill is disabled, and don't
|
| // provide credit card suggestions for non-HTTPS pages. However, provide a
|
| // warning to the user in these cases.
|
| @@ -502,10 +469,9 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
|
| warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION;
|
| }
|
| if (warning) {
|
| - values.assign(1, l10n_util::GetStringUTF16(warning));
|
| - labels.assign(1, base::string16());
|
| - icons.assign(1, base::string16());
|
| - unique_ids.assign(1, POPUP_ITEM_ID_WARNING_MESSAGE);
|
| + Suggestion warning_suggestion(l10n_util::GetStringUTF16(warning));
|
| + warning_suggestion.frontend_id = POPUP_ITEM_ID_WARNING_MESSAGE;
|
| + suggestions.assign(1, warning_suggestion);
|
| } else {
|
| bool section_is_autofilled =
|
| SectionIsAutofilled(*form_structure, form,
|
| @@ -515,8 +481,10 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
|
| // for suggestions, then the user is editing the value of a field.
|
| // In this case, mimic autocomplete: don't display labels or icons,
|
| // as that information is redundant.
|
| - labels.assign(labels.size(), base::string16());
|
| - icons.assign(icons.size(), base::string16());
|
| + for (size_t i = 0; i < suggestions.size(); i++) {
|
| + suggestions[i].label = base::string16();
|
| + suggestions[i].icon = base::string16();
|
| + }
|
| }
|
|
|
| // When filling credit card suggestions, the values and labels are
|
| @@ -524,12 +492,12 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
|
| // duplicates only tend to be a problem when filling address forms
|
| // anyway, only don't de-dup credit card suggestions.
|
| if (!is_filling_credit_card)
|
| - RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids);
|
| + RemoveDuplicateSuggestions(&suggestions);
|
|
|
| // The first time we show suggestions on this page, log the number of
|
| // suggestions shown.
|
| if (!has_logged_address_suggestions_count_ && !section_is_autofilled) {
|
| - metric_logger_->LogAddressSuggestionsCount(values.size());
|
| + metric_logger_->LogAddressSuggestionsCount(suggestions.size());
|
| has_logged_address_suggestions_count_ = true;
|
| }
|
| }
|
| @@ -541,14 +509,14 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
|
| // hand off what we generated and they will send the results back to the
|
| // renderer.
|
| autocomplete_history_manager_->OnGetAutocompleteSuggestions(
|
| - query_id, field.name, field.value, field.form_control_type, values,
|
| - labels, icons, unique_ids);
|
| + query_id, field.name, field.value, field.form_control_type,
|
| + suggestions);
|
| } else {
|
| // Autocomplete is disabled for this field; only pass back Autofill
|
| // suggestions.
|
| autocomplete_history_manager_->CancelPendingQuery();
|
| external_delegate_->OnSuggestionsReturned(
|
| - query_id, values, labels, icons, unique_ids);
|
| + query_id, suggestions);
|
| }
|
| }
|
|
|
| @@ -858,22 +826,22 @@ bool AutofillManager::GetProfileOrCreditCard(
|
| size_t* variant,
|
| bool* is_credit_card) const {
|
| // Unpack the |unique_id| into component parts.
|
| - GUIDPair credit_card_guid;
|
| - GUIDPair profile_guid;
|
| - UnpackGUIDs(unique_id, &credit_card_guid, &profile_guid);
|
| - DCHECK(!base::IsValidGUID(credit_card_guid.first) ||
|
| - !base::IsValidGUID(profile_guid.first));
|
| + SuggestionBackendID credit_card_id;
|
| + SuggestionBackendID profile_id;
|
| + SplitFrontendID(unique_id, &credit_card_id, &profile_id);
|
| + DCHECK(!base::IsValidGUID(credit_card_id.guid) ||
|
| + !base::IsValidGUID(profile_id.guid));
|
| *is_credit_card = false;
|
|
|
| // Find the profile that matches the |profile_guid|, if one is specified.
|
| // Otherwise find the credit card that matches the |credit_card_guid|,
|
| // if specified.
|
| - if (base::IsValidGUID(profile_guid.first)) {
|
| - *data_model = personal_data_->GetProfileByGUID(profile_guid.first);
|
| - *variant = profile_guid.second;
|
| - } else if (base::IsValidGUID(credit_card_guid.first)) {
|
| - *data_model = personal_data_->GetCreditCardByGUID(credit_card_guid.first);
|
| - *variant = credit_card_guid.second;
|
| + if (base::IsValidGUID(profile_id.guid)) {
|
| + *data_model = personal_data_->GetProfileByGUID(profile_id.guid);
|
| + *variant = profile_id.variant;
|
| + } else if (base::IsValidGUID(credit_card_id.guid)) {
|
| + *data_model = personal_data_->GetCreditCardByGUID(credit_card_id.guid);
|
| + *variant = credit_card_id.variant;
|
| *is_credit_card = true;
|
| }
|
|
|
| @@ -1136,53 +1104,44 @@ bool AutofillManager::UpdateCachedForm(const FormData& live_form,
|
| return true;
|
| }
|
|
|
| -void AutofillManager::GetProfileSuggestions(
|
| +std::vector<Suggestion> AutofillManager::GetProfileSuggestions(
|
| const FormStructure& form,
|
| const FormFieldData& field,
|
| - const AutofillField& autofill_field,
|
| - std::vector<base::string16>* values,
|
| - std::vector<base::string16>* labels,
|
| - std::vector<base::string16>* icons,
|
| - std::vector<int>* unique_ids) const {
|
| + const AutofillField& autofill_field) const {
|
| std::vector<ServerFieldType> field_types(form.field_count());
|
| for (size_t i = 0; i < form.field_count(); ++i) {
|
| field_types.push_back(form.field(i)->Type().GetStorableType());
|
| }
|
| - std::vector<GUIDPair> guid_pairs;
|
|
|
| - personal_data_->GetProfileSuggestions(
|
| + std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
|
| autofill_field.Type(), field.value, field.is_autofilled, field_types,
|
| - base::Callback<bool(const AutofillProfile&)>(),
|
| - values, labels, icons, &guid_pairs);
|
| + base::Callback<bool(const AutofillProfile&)>());
|
|
|
| // Adjust phone number to display in prefix/suffix case.
|
| if (autofill_field.Type().GetStorableType() == PHONE_HOME_NUMBER) {
|
| - for (size_t i = 0; i < values->size(); ++i) {
|
| - (*values)[i] = AutofillField::GetPhoneNumberValue(
|
| - autofill_field, (*values)[i], field);
|
| + for (size_t i = 0; i < suggestions.size(); ++i) {
|
| + suggestions[i].value = AutofillField::GetPhoneNumberValue(
|
| + autofill_field, suggestions[i].value, field);
|
| }
|
| }
|
|
|
| - for (size_t i = 0; i < guid_pairs.size(); ++i) {
|
| - unique_ids->push_back(PackGUIDs(GUIDPair(std::string(), 0),
|
| - guid_pairs[i]));
|
| + for (size_t i = 0; i < suggestions.size(); ++i) {
|
| + suggestions[i].frontend_id =
|
| + MakeFrontendID(SuggestionBackendID(), suggestions[i].backend_id);
|
| }
|
| + return suggestions;
|
| }
|
|
|
| -void AutofillManager::GetCreditCardSuggestions(
|
| +std::vector<Suggestion> AutofillManager::GetCreditCardSuggestions(
|
| const FormFieldData& field,
|
| - const AutofillType& type,
|
| - std::vector<base::string16>* values,
|
| - std::vector<base::string16>* labels,
|
| - std::vector<base::string16>* icons,
|
| - std::vector<int>* unique_ids) const {
|
| - std::vector<GUIDPair> guid_pairs;
|
| - personal_data_->GetCreditCardSuggestions(
|
| - type, field.value, values, labels, icons, &guid_pairs);
|
| -
|
| - for (size_t i = 0; i < guid_pairs.size(); ++i) {
|
| - unique_ids->push_back(PackGUIDs(guid_pairs[i], GUIDPair(std::string(), 0)));
|
| + const AutofillType& type) const {
|
| + std::vector<Suggestion> suggestions =
|
| + personal_data_->GetCreditCardSuggestions(type, field.value);
|
| + for (size_t i = 0; i < suggestions.size(); i++) {
|
| + suggestions[i].frontend_id =
|
| + MakeFrontendID(suggestions[i].backend_id, SuggestionBackendID());
|
| }
|
| + return suggestions;
|
| }
|
|
|
| void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
|
| @@ -1222,60 +1181,66 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
|
| driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms);
|
| }
|
|
|
| -int AutofillManager::GUIDToID(const GUIDPair& guid) const {
|
| - if (!base::IsValidGUID(guid.first))
|
| +int AutofillManager::BackendIDToInt(
|
| + const SuggestionBackendID& backend_id) const {
|
| + if (!base::IsValidGUID(backend_id.guid))
|
| return 0;
|
|
|
| - std::map<GUIDPair, int>::const_iterator iter = guid_id_map_.find(guid);
|
| - if (iter == guid_id_map_.end()) {
|
| - int id = guid_id_map_.size() + 1;
|
| - guid_id_map_[guid] = id;
|
| - id_guid_map_[id] = guid;
|
| - return id;
|
| - } else {
|
| - return iter->second;
|
| + const auto found = backend_to_int_map_.find(backend_id);
|
| + if (found == backend_to_int_map_.end()) {
|
| + // Unknown one, make a new entry.
|
| + int int_id = backend_to_int_map_.size() + 1;
|
| + backend_to_int_map_[backend_id] = int_id;
|
| + int_to_backend_map_[int_id] = backend_id;
|
| + return int_id;
|
| }
|
| + return found->second;
|
| }
|
|
|
| -const GUIDPair AutofillManager::IDToGUID(int id) const {
|
| - if (id == 0)
|
| - return GUIDPair(std::string(), 0);
|
| +SuggestionBackendID AutofillManager::IntToBackendID(int int_id) const {
|
| + if (int_id == 0)
|
| + return SuggestionBackendID();
|
|
|
| - std::map<int, GUIDPair>::const_iterator iter = id_guid_map_.find(id);
|
| - if (iter == id_guid_map_.end()) {
|
| + const auto found = int_to_backend_map_.find(int_id);
|
| + if (found == int_to_backend_map_.end()) {
|
| NOTREACHED();
|
| - return GUIDPair(std::string(), 0);
|
| + return SuggestionBackendID();
|
| }
|
| -
|
| - return iter->second;
|
| + return found->second;
|
| }
|
|
|
| // When sending IDs (across processes) to the renderer we pack credit card and
|
| // profile IDs into a single integer. Credit card IDs are sent in the high
|
| // word and profile IDs are sent in the low word.
|
| -int AutofillManager::PackGUIDs(const GUIDPair& cc_guid,
|
| - const GUIDPair& profile_guid) const {
|
| - int cc_id = GUIDToID(cc_guid);
|
| - int profile_id = GUIDToID(profile_guid);
|
| -
|
| - DCHECK(cc_id <= std::numeric_limits<unsigned short>::max());
|
| - DCHECK(profile_id <= std::numeric_limits<unsigned short>::max());
|
| -
|
| - return cc_id << std::numeric_limits<unsigned short>::digits | profile_id;
|
| +int AutofillManager::MakeFrontendID(
|
| + const SuggestionBackendID& cc_backend_id,
|
| + const SuggestionBackendID& profile_backend_id) const {
|
| + int cc_int_id = BackendIDToInt(cc_backend_id);
|
| + int profile_int_id = BackendIDToInt(profile_backend_id);
|
| +
|
| + // Should fit in signed 16-bit integers. We use 16-bits each when combining
|
| + // below, and negative frontend IDs have special meaning so we can never use
|
| + // the high bit.
|
| + DCHECK(cc_int_id <= std::numeric_limits<int16_t>::max());
|
| + DCHECK(profile_int_id <= std::numeric_limits<int16_t>::max());
|
| +
|
| + // Put CC in the high half of the bits.
|
| + return (cc_int_id << std::numeric_limits<uint16_t>::digits) | profile_int_id;
|
| }
|
|
|
| // When receiving IDs (across processes) from the renderer we unpack credit card
|
| // and profile IDs from a single integer. Credit card IDs are stored in the
|
| // high word and profile IDs are stored in the low word.
|
| -void AutofillManager::UnpackGUIDs(int id,
|
| - GUIDPair* cc_guid,
|
| - GUIDPair* profile_guid) const {
|
| - int cc_id = id >> std::numeric_limits<unsigned short>::digits &
|
| - std::numeric_limits<unsigned short>::max();
|
| - int profile_id = id & std::numeric_limits<unsigned short>::max();
|
| -
|
| - *cc_guid = IDToGUID(cc_id);
|
| - *profile_guid = IDToGUID(profile_id);
|
| +void AutofillManager::SplitFrontendID(
|
| + int frontend_id,
|
| + SuggestionBackendID* cc_backend_id,
|
| + SuggestionBackendID* profile_backend_id) const {
|
| + int cc_int_id = (frontend_id >> std::numeric_limits<uint16_t>::digits) &
|
| + std::numeric_limits<uint16_t>::max();
|
| + int profile_int_id = frontend_id & std::numeric_limits<uint16_t>::max();
|
| +
|
| + *cc_backend_id = IntToBackendID(cc_int_id);
|
| + *profile_backend_id = IntToBackendID(profile_int_id);
|
| }
|
|
|
| void AutofillManager::UpdateInitialInteractionTimestamp(
|
|
|