summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authordhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 20:01:54 +0000
committerdhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 20:01:54 +0000
commit061e81510e87f6f96c80a218e89cbdd82e815931 (patch)
tree744c0c0b842128aaa2fa801780cdf92dd3d55c6d /chrome
parentc223bd6a8115abb5069ba46651e62d44e67fad8f (diff)
downloadchromium_src-061e81510e87f6f96c80a218e89cbdd82e815931.zip
chromium_src-061e81510e87f6f96c80a218e89cbdd82e815931.tar.gz
chromium_src-061e81510e87f6f96c80a218e89cbdd82e815931.tar.bz2
Autofill extend profiles to include multi-valued fields, part 5 (Filling)
Reland. http://codereview.chromium.org/6810028 Modifies Autofill filling logic to use multi-valued fields where appropriate. There are two cases: (1) Filling unfilled forms. In this case the default behavior is unchanged. If however the user triggers suggestions with typed characters "Cy", say, then non-default values show up as suggestions if they match. In this example, if { "Bob", "Cynthia" } are two names in a profile, then "Cynthia" would show as a suggestion. (2) Filling previously filled forms. In this case suggestions are show for the matching string, *and* any secondary values if there are any. BUG=65625 TEST=AutofillManagerTest.GetFieldSuggestionsForMultiValuedProfile* Review URL: http://codereview.chromium.org/6822007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80974 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/autofill/autofill_manager.cc209
-rw-r--r--chrome/browser/autofill/autofill_manager.h24
-rw-r--r--chrome/browser/autofill/autofill_manager_unittest.cc207
-rw-r--r--chrome/browser/autofill/autofill_profile.cc14
4 files changed, 321 insertions, 133 deletions
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 64447b6..5cedc73 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -436,17 +436,18 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
DCHECK(autofill_field);
// Unpack the |unique_id| into component parts.
- std::string cc_guid;
- std::string profile_guid;
+ GUIDPair cc_guid;
+ GUIDPair profile_guid;
UnpackGUIDs(unique_id, &cc_guid, &profile_guid);
- DCHECK(!guid::IsValidGUID(cc_guid) || !guid::IsValidGUID(profile_guid));
+ DCHECK(!guid::IsValidGUID(cc_guid.first) ||
+ !guid::IsValidGUID(profile_guid.first));
// Find the profile that matches the |profile_id|, if one is specified.
const AutofillProfile* profile = NULL;
- if (guid::IsValidGUID(profile_guid)) {
+ if (guid::IsValidGUID(profile_guid.first)) {
for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
iter != profiles.end(); ++iter) {
- if ((*iter)->guid() == profile_guid) {
+ if ((*iter)->guid() == profile_guid.first) {
profile = *iter;
break;
}
@@ -456,10 +457,10 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
// Find the credit card that matches the |cc_id|, if one is specified.
const CreditCard* credit_card = NULL;
- if (guid::IsValidGUID(cc_guid)) {
+ if (guid::IsValidGUID(cc_guid.first)) {
for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
iter != credit_cards.end(); ++iter) {
- if ((*iter)->guid() == cc_guid) {
+ if ((*iter)->guid() == cc_guid.first) {
credit_card = *iter;
break;
}
@@ -487,7 +488,7 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
if (profile) {
DCHECK_NE(AutofillType::CREDIT_CARD,
AutofillType(field_type).group());
- FillFormField(profile, field_type, &(*iter));
+ FillFormField(profile, field_type, profile_guid.second, &(*iter));
} else {
DCHECK_EQ(AutofillType::CREDIT_CARD,
AutofillType(field_type).group());
@@ -528,7 +529,15 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
if (field_group_type != AutofillType::NO_GROUP) {
if (profile) {
DCHECK_NE(AutofillType::CREDIT_CARD, field_group_type);
- FillFormField(profile, field_type, &result.fields[j]);
+ // If the field being filled is the field that the user initiated the
+ // fill from, then take the multi-profile "variant" into account.
+ // Otherwise fill with the default (zeroth) variant.
+ if (result.fields[j] == field) {
+ FillFormField(profile, field_type, profile_guid.second,
+ &result.fields[j]);
+ } else {
+ FillFormField(profile, field_type, 0, &result.fields[j]);
+ }
} else {
DCHECK_EQ(AutofillType::CREDIT_CARD, field_group_type);
FillCreditCardFormField(credit_card, field_type, &result.fields[j]);
@@ -765,38 +774,76 @@ void AutofillManager::GetProfileSuggestions(FormStructure* form,
std::vector<string16>* icons,
std::vector<int>* unique_ids) {
const std::vector<AutofillProfile*>& profiles = personal_data_->profiles();
- std::vector<AutofillProfile*> matched_profiles;
- for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
- iter != profiles.end(); ++iter) {
- AutofillProfile* profile = *iter;
-
- // The value of the stored data for this field type in the |profile|.
- string16 profile_field_value = profile->GetInfo(type);
-
- if (!profile_field_value.empty() &&
- StartsWith(profile_field_value, field.value, false)) {
- matched_profiles.push_back(profile);
- values->push_back(profile_field_value);
- unique_ids->push_back(PackGUIDs(std::string(), profile->guid()));
+ if (!field.is_autofilled) {
+ std::vector<AutofillProfile*> matched_profiles;
+ for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
+ iter != profiles.end(); ++iter) {
+ AutofillProfile* profile = *iter;
+
+ // The value of the stored data for this field type in the |profile|.
+ std::vector<string16> multi_values;
+ profile->GetMultiInfo(type, &multi_values);
+
+ for (size_t i = 0; i < multi_values.size(); ++i) {
+ if (!multi_values[i].empty() &&
+ StartsWith(multi_values[i], field.value, false)) {
+ matched_profiles.push_back(profile);
+ values->push_back(multi_values[i]);
+ unique_ids->push_back(PackGUIDs(GUIDPair(std::string(), 0),
+ GUIDPair(profile->guid(), i)));
+ break;
+ }
+ }
}
- }
- std::vector<AutofillFieldType> form_fields;
- form_fields.reserve(form->field_count());
- for (std::vector<AutofillField*>::const_iterator iter = form->begin();
- iter != form->end(); ++iter) {
- // The field list is terminated with a NULL AutofillField, so don't try to
- // dereference it.
- if (!*iter)
- break;
- form_fields.push_back((*iter)->type());
- }
+ std::vector<AutofillFieldType> form_fields;
+ form_fields.reserve(form->field_count());
+ for (std::vector<AutofillField*>::const_iterator iter = form->begin();
+ iter != form->end(); ++iter) {
+ // The field list is terminated with a NULL AutofillField, so don't try to
+ // dereference it.
+ if (!*iter)
+ break;
+ form_fields.push_back((*iter)->type());
+ }
+
+ AutofillProfile::CreateInferredLabels(&matched_profiles, &form_fields,
+ type, 1, labels);
+
+ // No icons for profile suggestions.
+ icons->resize(values->size());
+ } else {
+ for (std::vector<AutofillProfile*>::const_iterator iter = profiles.begin();
+ iter != profiles.end(); ++iter) {
+ AutofillProfile* profile = *iter;
+
+ // The value of the stored data for this field type in the |profile|.
+ std::vector<string16> multi_values;
+ profile->GetMultiInfo(type, &multi_values);
+
+ for (size_t i = 0; i < multi_values.size(); ++i) {
+ if (!multi_values[i].empty() &&
+ StringToLowerASCII(multi_values[i])
+ == StringToLowerASCII(field.value)) {
+ for (size_t j = 0; j < multi_values.size(); ++j) {
+ if (!multi_values[j].empty()) {
+ values->push_back(multi_values[j]);
+ unique_ids->push_back(PackGUIDs(GUIDPair(std::string(), 0),
+ GUIDPair(profile->guid(), j)));
+ }
+ }
+ // We've added all the values for this profile so move on to the next.
+ break;
+ }
+ }
+ }
- AutofillProfile::CreateInferredLabels(&matched_profiles, &form_fields,
- type, 1, labels);
+ // No labels for previously filled fields.
+ labels->resize(values->size());
- // No icons for profile suggestions.
- icons->resize(values->size());
+ // No icons for profile suggestions.
+ icons->resize(values->size());
+ }
}
void AutofillManager::GetCreditCardSuggestions(FormStructure* form,
@@ -830,7 +877,8 @@ void AutofillManager::GetCreditCardSuggestions(FormStructure* form,
values->push_back(creditcard_field_value);
labels->push_back(label);
icons->push_back(credit_card->type());
- unique_ids->push_back(PackGUIDs(credit_card->guid(), std::string()));
+ unique_ids->push_back(PackGUIDs(GUIDPair(credit_card->guid(), 0),
+ GUIDPair(std::string(), 0)));
}
}
}
@@ -860,27 +908,36 @@ void AutofillManager::FillCreditCardFormField(const CreditCard* credit_card,
void AutofillManager::FillFormField(const AutofillProfile* profile,
AutofillFieldType type,
+ size_t variant,
webkit_glue::FormField* field) {
DCHECK(profile);
DCHECK_NE(AutofillType::CREDIT_CARD, AutofillType(type).group());
DCHECK(field);
if (AutofillType(type).subgroup() == AutofillType::PHONE_NUMBER) {
- FillPhoneNumberField(profile, type, field);
+ FillPhoneNumberField(profile, type, variant, field);
} else {
- if (field->form_control_type == ASCIIToUTF16("select-one"))
+ if (field->form_control_type == ASCIIToUTF16("select-one")) {
autofill::FillSelectControl(*profile, type, field);
- else
- field->value = profile->GetInfo(type);
+ } else {
+ std::vector<string16> values;
+ profile->GetMultiInfo(type, &values);
+ DCHECK(variant < values.size());
+ field->value = values[variant];
+ }
}
}
void AutofillManager::FillPhoneNumberField(const AutofillProfile* profile,
AutofillFieldType type,
+ size_t variant,
webkit_glue::FormField* field) {
// If we are filling a phone number, check to see if the size field
// matches the "prefix" or "suffix" sizes and fill accordingly.
- string16 number = profile->GetInfo(type);
+ std::vector<string16> values;
+ profile->GetMultiInfo(type, &values);
+ DCHECK(variant < values.size());
+ string16 number = values[variant];
bool has_valid_suffix_and_prefix = (number.length() ==
static_cast<size_t>(PhoneNumber::kPrefixLength +
PhoneNumber::kSuffixLength));
@@ -928,11 +985,40 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
}
}
+int AutofillManager::GUIDToID(const GUIDPair& guid) {
+ static int last_id = 1;
+
+ if (!guid::IsValidGUID(guid.first))
+ return 0;
+
+ std::map<GUIDPair, int>::const_iterator iter = guid_id_map_.find(guid);
+ if (iter == guid_id_map_.end()) {
+ guid_id_map_[guid] = last_id;
+ id_guid_map_[last_id] = guid;
+ return last_id++;
+ } else {
+ return iter->second;
+ }
+}
+
+const AutofillManager::GUIDPair AutofillManager::IDToGUID(int id) {
+ if (id == 0)
+ return GUIDPair(std::string(), 0);
+
+ std::map<int, GUIDPair>::const_iterator iter = id_guid_map_.find(id);
+ if (iter == id_guid_map_.end()) {
+ NOTREACHED();
+ return GUIDPair(std::string(), 0);
+ }
+
+ return iter->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 std::string& cc_guid,
- const std::string& profile_guid) {
+int AutofillManager::PackGUIDs(const GUIDPair& cc_guid,
+ const GUIDPair& profile_guid) {
int cc_id = GUIDToID(cc_guid);
int profile_id = GUIDToID(profile_guid);
@@ -946,8 +1032,8 @@ int AutofillManager::PackGUIDs(const std::string& cc_guid,
// 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,
- std::string* cc_guid,
- std::string* profile_guid) {
+ GUIDPair* cc_guid,
+ GUIDPair* profile_guid) {
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();
@@ -955,32 +1041,3 @@ void AutofillManager::UnpackGUIDs(int id,
*cc_guid = IDToGUID(cc_id);
*profile_guid = IDToGUID(profile_id);
}
-
-int AutofillManager::GUIDToID(const std::string& guid) {
- static int last_id = 1;
-
- if (!guid::IsValidGUID(guid))
- return 0;
-
- std::map<std::string, int>::const_iterator iter = guid_id_map_.find(guid);
- if (iter == guid_id_map_.end()) {
- guid_id_map_[guid] = last_id;
- id_guid_map_[last_id] = guid;
- return last_id++;
- } else {
- return iter->second;
- }
-}
-
-const std::string AutofillManager::IDToGUID(int id) {
- if (id == 0)
- return std::string();
-
- std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id);
- if (iter == id_guid_map_.end()) {
- NOTREACHED();
- return std::string();
- }
-
- return iter->second;
-}
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index 26667c0..2bdbb20 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -84,7 +84,13 @@ class AutofillManager : public TabContentsObserver,
void Reset();
protected:
- // For tests.
+ // For tests:
+
+ // The string/int pair is composed of the guid string and variant index
+ // respectively. The variant index is an index into the multi-valued item
+ // (where applicable).
+ typedef std::pair<std::string, size_t> GUIDPair;
+
AutofillManager(TabContents* tab_contents,
PersonalDataManager* personal_data);
@@ -99,13 +105,13 @@ class AutofillManager : public TabContentsObserver,
// Maps GUIDs to and from IDs that are used to identify profiles and credit
// cards sent to and from the renderer process.
- virtual int GUIDToID(const std::string& guid);
- virtual const std::string IDToGUID(int id);
+ virtual int GUIDToID(const GUIDPair& guid);
+ virtual const GUIDPair IDToGUID(int id);
// Methods for packing and unpacking credit card and profile IDs for sending
// and receiving to and from the renderer process.
- int PackGUIDs(const std::string& cc_guid, const std::string& profile_guid);
- void UnpackGUIDs(int id, std::string* cc_guid, std::string* profile_guid);
+ int PackGUIDs(const GUIDPair& cc_guid, const GUIDPair& profile_guid);
+ void UnpackGUIDs(int id, GUIDPair* cc_guid, GUIDPair* profile_guid);
private:
void OnFormSubmitted(const webkit_glue::FormData& form);
@@ -169,14 +175,18 @@ class AutofillManager : public TabContentsObserver,
webkit_glue::FormField* field);
// Set |field| argument's value based on |type| and contents of the |profile|.
+ // The |variant| parameter specifies which value in a multi-valued profile.
void FillFormField(const AutofillProfile* profile,
AutofillFieldType type,
+ size_t variant,
webkit_glue::FormField* field);
// Set |field| argument's value for phone/fax number based on contents of the
// |profile|. |type| is the type of the phone.
+ // The |variant| parameter specifies which value in a multi-valued profile.
void FillPhoneNumberField(const AutofillProfile* profile,
AutofillFieldType type,
+ size_t variant,
webkit_glue::FormField* field);
// Parses the forms using heuristic matching and querying the Autofill server.
@@ -217,8 +227,8 @@ class AutofillManager : public TabContentsObserver,
bool has_logged_address_suggestions_count_;
// GUID to ID mapping. We keep two maps to convert back and forth.
- std::map<std::string, int> guid_id_map_;
- std::map<int, std::string> id_guid_map_;
+ std::map<GUIDPair, int> guid_id_map_;
+ std::map<int, GUIDPair> id_guid_map_;
friend class AutofillManagerTest;
friend class FormStructureBrowserTest;
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc
index 04c5cc8..646b0fa 100644
--- a/chrome/browser/autofill/autofill_manager_unittest.cc
+++ b/chrome/browser/autofill/autofill_manager_unittest.cc
@@ -434,24 +434,25 @@ class TestAutofillManager : public AutofillManager {
}
int GetPackedCreditCardID(int credit_card_id) {
- return PackGUIDs(IDToGUID(credit_card_id), std::string());
+ return PackGUIDs(IDToGUID(credit_card_id), GUIDPair(std::string(), 0));
}
- virtual int GUIDToID(const std::string& guid) OVERRIDE {
- if (guid.empty())
+ virtual int GUIDToID(const GUIDPair& guid) OVERRIDE {
+ if (guid.first.empty())
return 0;
int id;
- EXPECT_TRUE(base::StringToInt(guid.substr(guid.rfind("-") + 1), &id));
+ EXPECT_TRUE(base::StringToInt(guid.first.substr(guid.first.rfind("-") + 1),
+ &id));
return id;
}
- virtual const std::string IDToGUID(int id) OVERRIDE {
+ virtual const GUIDPair IDToGUID(int id) OVERRIDE {
EXPECT_TRUE(id >= 0);
if (id <= 0)
- return std::string();
+ return GUIDPair(std::string(), 0);
- return base::StringPrintf("00000000-0000-0000-0000-%012d", id);
+ return GUIDPair(base::StringPrintf("00000000-0000-0000-0000-%012d", id), 0);
}
private:
@@ -465,6 +466,8 @@ class TestAutofillManager : public AutofillManager {
class AutofillManagerTest : public TabContentsWrapperTestHarness {
public:
+ typedef AutofillManager::GUIDPair GUIDPair;
+
AutofillManagerTest() {}
virtual ~AutofillManagerTest() {
// Order of destruction is important as AutofillManager relies on
@@ -1338,6 +1341,7 @@ TEST_F(AutofillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
FormField& field = form.fields[0];
field.is_autofilled = true;
+ field.value = ASCIIToUTF16("Elvis");
GetAutofillSuggestions(form, field);
// No suggestions provided, so send an empty vector as the results.
@@ -1353,13 +1357,108 @@ TEST_F(AutofillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
&unique_ids));
+ string16 expected_values[] = { ASCIIToUTF16("Elvis") };
+ string16 expected_labels[] = { string16() };
+ string16 expected_icons[] = { string16() };
+ int expected_unique_ids[] = { 1 };
+ ExpectSuggestions(page_id, values, labels, icons, unique_ids,
+ kDefaultPageID, arraysize(expected_values), expected_values,
+ expected_labels, expected_icons, expected_unique_ids);
+}
+
+// Test that a non-default value is suggested for multi-valued profile, on an
+// unfilled form.
+TEST_F(AutofillManagerTest, GetFieldSuggestionsForMultiValuedProfileUnfilled) {
+ // Set up our form data.
+ FormData form;
+ CreateTestAddressFormData(&form);
+ std::vector<FormData> forms(1, form);
+ FormsSeen(forms);
+
+ // |profile| will be owned by the mock PersonalDataManager.
+ AutofillProfile* profile = new AutofillProfile;
+ autofill_test::SetProfileInfo(profile, "Elvis", "", "Presley", "me@x.com", "",
+ "", "", "", "", "", "", "", "");
+ profile->set_guid("00000000-0000-0000-0000-000000000101");
+ std::vector<string16> multi_values(2);
+ multi_values[0] = ASCIIToUTF16("Elvis Presley");
+ multi_values[1] = ASCIIToUTF16("Cynthia Love");
+ profile->SetMultiInfo(NAME_FULL, multi_values);
+ autofill_manager_->AddProfile(profile);
+
+ // Get the first name field. And start out with "Cy", hoping for "Cynthia".
+ FormField& field = form.fields[0];
+ field.value = ASCIIToUTF16("Cy");
+ field.is_autofilled = false;
+ GetAutofillSuggestions(form, field);
+
+ // Trigger the |Send|.
+ AutocompleteSuggestionsReturned(std::vector<string16>());
+
+ // Test that we sent the right message to the renderer.
+ int page_id = 0;
+ std::vector<string16> values;
+ std::vector<string16> labels;
+ std::vector<string16> icons;
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
+
+ string16 expected_values[] = { ASCIIToUTF16("Cynthia") };
+ string16 expected_labels[] = { ASCIIToUTF16("me@x.com") };
+ string16 expected_icons[] = { string16() };
+ int expected_unique_ids[] = { 101 };
+ ExpectSuggestions(page_id, values, labels, icons, unique_ids,
+ kDefaultPageID, arraysize(expected_values), expected_values,
+ expected_labels, expected_icons, expected_unique_ids);
+}
+
+// Test that all values are suggested for multi-valued profile, on a filled
+// form. This is the per-field "override" case.
+TEST_F(AutofillManagerTest, GetFieldSuggestionsForMultiValuedProfileFilled) {
+ // Set up our form data.
+ FormData form;
+ CreateTestAddressFormData(&form);
+ std::vector<FormData> forms(1, form);
+ FormsSeen(forms);
+
+ // |profile| will be owned by the mock PersonalDataManager.
+ AutofillProfile* profile = new AutofillProfile;
+ profile->set_guid("00000000-0000-0000-0000-000000000102");
+ std::vector<string16> multi_values(3);
+ multi_values[0] = ASCIIToUTF16("Travis Smith");
+ multi_values[1] = ASCIIToUTF16("Cynthia Love");
+ multi_values[2] = ASCIIToUTF16("Zac Mango");
+ profile->SetMultiInfo(NAME_FULL, multi_values);
+ autofill_manager_->AddProfile(profile);
+
+ // Get the first name field. And start out with "Travis", hoping for all the
+ // multi-valued variants as suggestions.
+ FormField& field = form.fields[0];
+ field.value = ASCIIToUTF16("Travis");
+ field.is_autofilled = true;
+ GetAutofillSuggestions(form, field);
+
+ // Trigger the |Send|.
+ AutocompleteSuggestionsReturned(std::vector<string16>());
+
+ // Test that we sent the right message to the renderer.
+ int page_id = 0;
+ std::vector<string16> values;
+ std::vector<string16> labels;
+ std::vector<string16> icons;
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
+
string16 expected_values[] = {
- ASCIIToUTF16("Elvis"),
- ASCIIToUTF16("Charles")
+ ASCIIToUTF16("Travis"),
+ ASCIIToUTF16("Cynthia"),
+ ASCIIToUTF16("Zac")
};
- string16 expected_labels[] = {string16(), string16()};
- string16 expected_icons[] = {string16(), string16()};
- int expected_unique_ids[] = {1, 2};
+ string16 expected_labels[] = { string16(), string16(), string16() };
+ string16 expected_icons[] = { string16(), string16(), string16() };
+ int expected_unique_ids[] = { 102, 102, 102 };
ExpectSuggestions(page_id, values, labels, icons, unique_ids,
kDefaultPageID, arraysize(expected_values), expected_values,
expected_labels, expected_icons, expected_unique_ids);
@@ -1373,10 +1472,11 @@ TEST_F(AutofillManagerTest, FillAddressForm) {
std::vector<FormData> forms(1, form);
FormsSeen(forms);
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1392,10 +1492,11 @@ TEST_F(AutofillManagerTest, FillCreditCardForm) {
std::vector<FormData> forms(1, form);
FormsSeen(forms);
- std::string guid = "00000000-0000-0000-0000-000000000004";
+ GUIDPair guid("00000000-0000-0000-0000-000000000004", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid, empty));
int page_id = 0;
FormData results;
@@ -1415,10 +1516,11 @@ TEST_F(AutofillManagerTest, FillCreditCardFormNoYearNoMonth) {
std::vector<FormData> forms(1, form);
FormsSeen(forms);
- std::string guid = "00000000-0000-0000-0000-000000000007";
+ GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid, empty));
int page_id = 0;
FormData results;
@@ -1440,10 +1542,11 @@ TEST_F(AutofillManagerTest, FillCreditCardFormNoYearMonth) {
std::vector<FormData> forms(1, form);
FormsSeen(forms);
- std::string guid = "00000000-0000-0000-0000-000000000007";
+ GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid, empty));
int page_id = 0;
FormData results;
@@ -1464,10 +1567,11 @@ TEST_F(AutofillManagerTest, FillCreditCardFormYearNoMonth) {
std::vector<FormData> forms(1, form);
FormsSeen(forms);
- std::string guid = "00000000-0000-0000-0000-000000000007";
+ GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid, empty));
int page_id = 0;
FormData results;
@@ -1489,10 +1593,11 @@ TEST_F(AutofillManagerTest, FillCreditCardFormYearMonth) {
std::vector<FormData> forms(1, form);
FormsSeen(forms);
- std::string guid = "00000000-0000-0000-0000-000000000007";
+ GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid, empty));
int page_id = 0;
FormData results;
@@ -1511,9 +1616,10 @@ TEST_F(AutofillManagerTest, FillAddressAndCreditCardForm) {
FormsSeen(forms);
// First fill the address data.
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1525,10 +1631,10 @@ TEST_F(AutofillManagerTest, FillAddressAndCreditCardForm) {
// Now fill the credit card data.
const int kPageID2 = 2;
- guid = "00000000-0000-0000-0000-000000000004";
+ GUIDPair guid2("00000000-0000-0000-0000-000000000004", 0);
FillAutofillFormData(
kPageID2, form, form.fields.back(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid2, empty));
page_id = 0;
EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
@@ -1554,9 +1660,10 @@ TEST_F(AutofillManagerTest, FillFormWithMultipleSections) {
FormsSeen(forms);
// Fill the first section.
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1578,10 +1685,10 @@ TEST_F(AutofillManagerTest, FillFormWithMultipleSections) {
// Fill the second section, with the initiating field somewhere in the middle
// of the section.
const int kPageID2 = 2;
- guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid2("00000000-0000-0000-0000-000000000001", 0);
ASSERT_LT(9U, kAddressFormSize);
FillAutofillFormData(kPageID2, form, form.fields[kAddressFormSize + 9],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid2));
page_id = 0;
EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
@@ -1624,9 +1731,10 @@ TEST_F(AutofillManagerTest, FillFormWithMultipleEmails) {
FormsSeen(forms);
// Fill the form.
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1652,10 +1760,11 @@ TEST_F(AutofillManagerTest, FillAutofilledForm) {
FormsSeen(forms);
// First fill the address data.
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1669,10 +1778,10 @@ TEST_F(AutofillManagerTest, FillAutofilledForm) {
// Now fill the credit card data.
const int kPageID2 = 2;
- guid = "00000000-0000-0000-0000-000000000004";
+ GUIDPair guid2("00000000-0000-0000-0000-000000000004", 0);
FillAutofillFormData(
kPageID2, form, form.fields.back(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid2, empty));
page_id = 0;
EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
@@ -1692,7 +1801,7 @@ TEST_F(AutofillManagerTest, FillAutofilledForm) {
const int kPageID3 = 3;
FillAutofillFormData(
kPageID3, form, *form.fields.rbegin(),
- autofill_manager_->PackGUIDs(guid, std::string()));
+ autofill_manager_->PackGUIDs(guid2, empty));
page_id = 0;
EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
@@ -1744,6 +1853,9 @@ TEST_F(AutofillManagerTest, FillPhoneNumber) {
ASSERT_TRUE(work_profile != NULL);
string16 saved_phone = work_profile->GetInfo(PHONE_HOME_NUMBER);
+ GUIDPair guid(work_profile->guid(), 0);
+ GUIDPair empty(std::string(), 0);
+
char test_data[] = "1234567890123456";
for (int i = arraysize(test_data) - 1; i >= 0; --i) {
test_data[i] = 0;
@@ -1754,7 +1866,7 @@ TEST_F(AutofillManagerTest, FillPhoneNumber) {
int page_id = 100 - i;
FillAutofillFormData(
page_id, form, *form.fields.begin(),
- autofill_manager_->PackGUIDs(std::string(), work_profile->guid()));
+ autofill_manager_->PackGUIDs(empty, guid));
page_id = 0;
FormData results;
EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
@@ -1789,10 +1901,11 @@ TEST_F(AutofillManagerTest, FormChangesRemoveField) {
// Now, after the call to |FormsSeen|, we remove the field before filling.
form.fields.erase(form.fields.begin() + 3);
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1820,10 +1933,11 @@ TEST_F(AutofillManagerTest, FormChangesAddField) {
// Now, after the call to |FormsSeen|, we restore the field before filling.
form.fields.insert(pos, field);
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(
kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
@@ -1840,9 +1954,10 @@ TEST_F(AutofillManagerTest, FormSubmitted) {
FormsSeen(forms);
// Fill the form.
- std::string guid = "00000000-0000-0000-0000-000000000001";
+ GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
+ GUIDPair empty(std::string(), 0);
FillAutofillFormData(kDefaultPageID, form, form.fields[0],
- autofill_manager_->PackGUIDs(std::string(), guid));
+ autofill_manager_->PackGUIDs(empty, guid));
int page_id = 0;
FormData results;
diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc
index 890f726..7a526cc 100644
--- a/chrome/browser/autofill/autofill_profile.cc
+++ b/chrome/browser/autofill/autofill_profile.cc
@@ -219,7 +219,14 @@ void AutofillProfile::SetMultiInfo(AutofillFieldType type,
CopyValuesToItems(type, values, &fax_number_);
break;
default:
- NOTREACHED() << "Attempt to set multiple values on single-valued field.";
+ if (values.size() == 1) {
+ SetInfo(type, values[0]);
+ } else if (values.size() == 0) {
+ SetInfo(type, string16());
+ } else {
+ NOTREACHED()
+ << "Attempt to set multiple values on single-valued field.";
+ }
break;
}
}
@@ -240,9 +247,8 @@ void AutofillProfile::GetMultiInfo(AutofillFieldType type,
CopyItemsToValues(type, fax_number_, values);
break;
default:
- NOTREACHED()
- << "Attempt to get multiple values from a single-valued field.";
- break;
+ values->resize(1);
+ (*values)[0] = GetInfo(type);
}
}