Only detect heuristic autofill types on page load (not on form submission).

BUG=75862, 76034
TEST=none

Review URL: http://codereview.chromium.org/6673033

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78336 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index f29068d..1c0fd81 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -875,6 +875,8 @@
     if (!form_structure->ShouldBeParsed(false))
       continue;
 
+    form_structure->DetermineHeuristicTypes();
+
     // Set aside forms with method GET so that they are not included in the
     // query to the server.
     if (form_structure->ShouldBeParsed(true))
diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc
index 6cfb885..a86aaa80 100644
--- a/chrome/browser/autofill/form_structure.cc
+++ b/chrome/browser/autofill/form_structure.cc
@@ -68,7 +68,6 @@
 
   // Terminate the vector with a NULL item.
   fields_.push_back(NULL);
-  GetHeuristicAutofillTypes();
 
   std::string method = UTF16ToUTF8(form.method);
   if (StringToLowerASCII(method) == kFormMethodPost) {
@@ -82,6 +81,37 @@
 
 FormStructure::~FormStructure() {}
 
+void FormStructure::DetermineHeuristicTypes() {
+  has_credit_card_field_ = false;
+  has_autofillable_field_ = false;
+  autofill_count_ = 0;
+
+  FieldTypeMap field_type_map;
+  GetHeuristicFieldInfo(&field_type_map);
+
+  for (size_t index = 0; index < field_count(); index++) {
+    AutofillField* field = fields_[index];
+    DCHECK(field);
+    FieldTypeMap::iterator iter = field_type_map.find(field->unique_name());
+
+    AutofillFieldType heuristic_auto_fill_type;
+    if (iter == field_type_map.end()) {
+      heuristic_auto_fill_type = UNKNOWN_TYPE;
+    } else {
+      heuristic_auto_fill_type = iter->second;
+      ++autofill_count_;
+    }
+
+    field->set_heuristic_type(heuristic_auto_fill_type);
+
+    AutofillType autofill_type(field->type());
+    if (autofill_type.group() == AutofillType::CREDIT_CARD)
+      has_credit_card_field_ = true;
+    if (autofill_type.field_type() != UNKNOWN_TYPE)
+      has_autofillable_field_ = true;
+  }
+}
+
 bool FormStructure::EncodeUploadRequest(bool auto_fill_used,
                                         std::string* encoded_xml) const {
   DCHECK(encoded_xml);
@@ -433,36 +463,6 @@
   return base::Uint64ToString(hash64);
 }
 
-void FormStructure::GetHeuristicAutofillTypes() {
-  has_credit_card_field_ = false;
-  has_autofillable_field_ = false;
-
-  FieldTypeMap field_type_map;
-  GetHeuristicFieldInfo(&field_type_map);
-
-  for (size_t index = 0; index < field_count(); index++) {
-    AutofillField* field = fields_[index];
-    DCHECK(field);
-    FieldTypeMap::iterator iter = field_type_map.find(field->unique_name());
-
-    AutofillFieldType heuristic_auto_fill_type;
-    if (iter == field_type_map.end()) {
-      heuristic_auto_fill_type = UNKNOWN_TYPE;
-    } else {
-      heuristic_auto_fill_type = iter->second;
-      ++autofill_count_;
-    }
-
-    field->set_heuristic_type(heuristic_auto_fill_type);
-
-    AutofillType autofill_type(field->type());
-    if (autofill_type.group() == AutofillType::CREDIT_CARD)
-      has_credit_card_field_ = true;
-    if (autofill_type.field_type() != UNKNOWN_TYPE)
-      has_autofillable_field_ = true;
-  }
-}
-
 void FormStructure::GetHeuristicFieldInfo(FieldTypeMap* field_type_map) {
   FormFieldSet fields(this);
 
diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h
index 597ff9b..2c58f97 100644
--- a/chrome/browser/autofill/form_structure.h
+++ b/chrome/browser/autofill/form_structure.h
@@ -40,6 +40,10 @@
   explicit FormStructure(const webkit_glue::FormData& form);
   virtual ~FormStructure();
 
+  // Runs several heuristics against the form fields to determine their possible
+  // types.
+  void DetermineHeuristicTypes();
+
   // Encodes the XML upload request from this FormStructure.
   bool EncodeUploadRequest(bool auto_fill_used, std::string* encoded_xml) const;
 
@@ -128,10 +132,6 @@
     UPLOAD,
   };
 
-  // Runs several heuristics against the form fields to determine their possible
-  // types.
-  void GetHeuristicAutofillTypes();
-
   // Associates the field with the heuristic type for each of the field views.
   void GetHeuristicFieldInfo(FieldTypeMap* field_types_map);
 
diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc
index f4d1cb99..bc20d49 100644
--- a/chrome/browser/autofill/form_structure_unittest.cc
+++ b/chrome/browser/autofill/form_structure_unittest.cc
@@ -103,6 +103,7 @@
                                                0,
                                                false));
   FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
 
   // Only text and select fields that are heuristically matched are counted.
   EXPECT_EQ(1U, form_structure.autofill_count());
@@ -136,6 +137,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->HasAutoFillableValues());
 
   // Empty text/select fields are also not used when saving auto fill data.
@@ -152,6 +154,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->HasAutoFillableValues());
 
   // Non-empty fields can be saved in auto fill profile.
@@ -168,6 +171,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->HasAutoFillableValues());
 
   // The fields must be recognized heuristically by AutoFill in addition to
@@ -186,6 +190,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->HasAutoFillableValues());
 
   // Add a field that we match heuristically, verify that this form has
@@ -197,6 +202,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->HasAutoFillableValues());
 }
 
@@ -225,6 +231,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->IsAutoFillable(true));
 
   // We now have three text fields, but only two auto-fillable fields.
@@ -241,6 +248,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->IsAutoFillable(true));
 
   // We now have three auto-fillable fields.
@@ -251,12 +259,14 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
 
   // The method must be 'post', though we can intentionally ignore this
   // criterion for the sake of providing a helpful warning message to the user.
   form.method = ASCIIToUTF16("get");
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->IsAutoFillable(true));
   EXPECT_TRUE(form_structure->IsAutoFillable(false));
 
@@ -264,11 +274,13 @@
   form.method = ASCIIToUTF16("post");
   form.action = GURL("http://google.com/search?q=hello");
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_FALSE(form_structure->IsAutoFillable(true));
 
   // But search can be in the URL.
   form.action = GURL("http://search.com/?q=hello");
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
 }
 
@@ -332,6 +344,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
 
   // Expect the correct number of fields.
@@ -435,6 +448,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(10U, form_structure->field_count());
   ASSERT_EQ(9U, form_structure->autofill_count());
@@ -520,6 +534,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(7U, form_structure->field_count());
   ASSERT_EQ(6U, form_structure->autofill_count());
@@ -603,6 +618,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(9U, form_structure->field_count());
   ASSERT_EQ(8U, form_structure->autofill_count());
@@ -670,6 +686,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(6U, form_structure->field_count());
   ASSERT_EQ(4U, form_structure->autofill_count());
@@ -739,6 +756,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(7U, form_structure->field_count());
   ASSERT_EQ(4U, form_structure->autofill_count());
@@ -794,6 +812,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(4U, form_structure->field_count());
   ASSERT_EQ(3U, form_structure->autofill_count());
@@ -844,6 +863,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(4U, form_structure->field_count());
   ASSERT_EQ(4U, form_structure->autofill_count());
@@ -898,6 +918,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(4U, form_structure->field_count());
   ASSERT_EQ(3U, form_structure->autofill_count());
@@ -942,6 +963,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(3U, form_structure->field_count());
   ASSERT_EQ(3U, form_structure->autofill_count());
@@ -981,6 +1003,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(3U, form_structure->field_count());
   ASSERT_EQ(3U, form_structure->autofill_count());
@@ -1077,6 +1100,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(11U, form_structure->field_count());
   ASSERT_EQ(11U, form_structure->autofill_count());
@@ -1132,6 +1156,7 @@
                              0,
                              false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
   ASSERT_EQ(4U, form_structure->field_count());
   ASSERT_EQ(3U, form_structure->autofill_count());
@@ -1183,6 +1208,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
 
   // Expect the correct number of fields.
@@ -1243,6 +1269,7 @@
                                                0,
                                                false));
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   EXPECT_TRUE(form_structure->IsAutoFillable(true));
 
   // Expect the correct number of fields.
@@ -1390,6 +1417,7 @@
   FormData form;
   form.method = ASCIIToUTF16("post");
   form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
                         ASCIIToUTF16("firstname"),
                         string16(),
diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc
index 2575239..6ae07e4 100644
--- a/chrome/browser/autofill/personal_data_manager_unittest.cc
+++ b/chrome/browser/autofill/personal_data_manager_unittest.cc
@@ -542,6 +542,7 @@
       "Zip:", "zip", "94102", "text", &field);
   form.fields.push_back(field);
   FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure);
   const CreditCard* imported_credit_card;
@@ -588,6 +589,7 @@
       "Zip:", "zip", "94102", "text", &field);
   form.fields.push_back(field);
   FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure);
   const CreditCard* imported_credit_card;
@@ -622,6 +624,7 @@
       "Card number:", "card_number", "4111 1111 1111 1111", "text", &field);
   form.fields.push_back(field);
   FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure);
   const CreditCard* imported_credit_card;
@@ -674,6 +677,7 @@
       "Zip:", "zip", "94102", "text", &field);
   form.fields.push_back(field);
   FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure);
   const CreditCard* imported_credit_card;
@@ -776,6 +780,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -821,6 +826,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -876,6 +882,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -933,6 +940,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -978,6 +986,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1023,6 +1032,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1073,6 +1083,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1119,6 +1130,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1160,6 +1172,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1198,6 +1211,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1235,6 +1249,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1276,6 +1291,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1313,6 +1329,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_FALSE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1344,6 +1361,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1382,6 +1400,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1424,6 +1443,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1458,6 +1478,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_FALSE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1493,6 +1514,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1529,6 +1551,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_FALSE(personal_data_->ImportFormData(forms, &imported_credit_card));
@@ -1562,6 +1585,7 @@
   form1.fields.push_back(field);
 
   FormStructure form_structure1(form1);
+  form_structure1.DetermineHeuristicTypes();
   std::vector<const FormStructure*> forms;
   forms.push_back(&form_structure1);
   const CreditCard* imported_credit_card;
@@ -1600,6 +1624,7 @@
   form2.fields.push_back(field);
 
   FormStructure form_structure2(form2);
+  form_structure2.DetermineHeuristicTypes();
   forms.clear();
   forms.push_back(&form_structure2);
   EXPECT_TRUE(personal_data_->ImportFormData(forms, &imported_credit_card));