For input and textarea fields send these events:

Focus
KeyDown
Change (already present)
Input (already present)
KeyUp
Blur

For select fields send these events:

Focus
Change (already present)
Input (already present)
Blur

BUG=581537
TEST=AutofillInteractiveTest

Review-Url: https://codereview.chromium.org/1955963002
Cr-Commit-Position: refs/heads/master@{#392842}
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index 045f6924..5775936 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -103,6 +103,66 @@
     "<input type=\"submit\" value=\"Submit\">"
     "</form>";
 
+// TODO(crbug.com/609861): Remove the autocomplete attribute from the textarea
+// field when the bug is fixed.
+static const char kTestEventFormString[] =
+    "<script type=\"text/javascript\">"
+    "var inputfocus = false;"
+    "var inputkeydown = false;"
+    "var inputinput = false;"
+    "var inputchange = false;"
+    "var inputkeyup = false;"
+    "var inputblur = false;"
+    "var textfocus = false;"
+    "var textkeydown = false;"
+    "var textinput= false;"
+    "var textchange = false;"
+    "var textkeyup = false;"
+    "var textblur = false;"
+    "var selectfocus = false;"
+    "var selectinput = false;"
+    "var selectchange = false;"
+    "var selectblur = false;"
+    "</script>"
+    "<form action=\"http://www.example.com/\" method=\"POST\">"
+    "<label for=\"firstname\">First name:</label>"
+    " <input type=\"text\" id=\"firstname\""
+    "        onfocus=\"domAutomationController.send(true)\"><br>"
+    "<label for=\"lastname\">Last name:</label>"
+    " <input type=\"text\" id=\"lastname\""
+    " onfocus=\"inputfocus = true\" onkeydown=\"inputkeydown = true\""
+    " oninput=\"inputinput = true\" onchange=\"inputchange = true\""
+    " onkeyup=\"inputkeyup = true\" onblur=\"inputblur = true\" ><br>"
+    "<label for=\"address1\">Address line 1:</label>"
+    " <input type=\"text\" id=\"address1\"><br>"
+    "<label for=\"address2\">Address line 2:</label>"
+    " <input type=\"text\" id=\"address2\"><br>"
+    "<label for=\"city\">City:</label>"
+    " <textarea rows=\"4\" cols=\"50\" id=\"city\" name=\"city\""
+    " autocomplete=\"address-level2\" onfocus=\"textfocus = true\""
+    " onkeydown=\"textkeydown = true\" oninput=\"textinput = true\""
+    " onchange=\"textchange = true\" onkeyup=\"textkeyup = true\""
+    " onblur=\"textblur = true\"></textarea><br>"
+    "<label for=\"state\">State:</label>"
+    " <select id=\"state\""
+    " onfocus=\"selectfocus = true\" oninput=\"selectinput = true\""
+    " onchange=\"selectchange = true\" onblur=\"selectblur = true\" >"
+    " <option value=\"\" selected=\"yes\">--</option>"
+    " <option value=\"CA\">California</option>"
+    " <option value=\"TX\">Texas</option>"
+    " </select><br>"
+    "<label for=\"zip\">ZIP code:</label>"
+    " <input type=\"text\" id=\"zip\"><br>"
+    "<label for=\"country\">Country:</label>"
+    " <select id=\"country\">"
+    " <option value=\"\" selected=\"yes\">--</option>"
+    " <option value=\"CA\">Canada</option>"
+    " <option value=\"US\">United States</option>"
+    " </select><br>"
+    "<label for=\"phone\">Phone number:</label>"
+    " <input type=\"text\" id=\"phone\"><br>"
+    "</form>";
+
 // AutofillManagerTestDelegateImpl --------------------------------------------
 
 class AutofillManagerTestDelegateImpl
@@ -1180,6 +1240,105 @@
   TryBasicFormFill();
 }
 
+// Test that filling a form sends all the expected events to the different
+// fields being filled.
+IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, AutofillEvents) {
+  CreateTestProfile();
+
+  // Load the test page.
+  ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
+      browser(), GURL(std::string(kDataURIPrefix) + kTestEventFormString)));
+
+  // Invoke Autofill.
+  TryBasicFormFill();
+
+  // Checks that all the events were fired for the input field.
+  bool input_focus_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(inputfocus);",
+      &input_focus_triggered));
+  EXPECT_TRUE(input_focus_triggered);
+  bool input_keydown_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(inputkeydown);",
+      &input_keydown_triggered));
+  EXPECT_TRUE(input_keydown_triggered);
+  bool input_input_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(inputinput);",
+      &input_input_triggered));
+  EXPECT_TRUE(input_input_triggered);
+  bool input_change_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(inputchange);",
+      &input_change_triggered));
+  EXPECT_TRUE(input_change_triggered);
+  bool input_keyup_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(inputkeyup);",
+      &input_keyup_triggered));
+  EXPECT_TRUE(input_keyup_triggered);
+  bool input_blur_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(inputblur);",
+      &input_blur_triggered));
+  EXPECT_TRUE(input_blur_triggered);
+
+  // Checks that all the events were fired for the textarea field.
+  bool text_focus_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(textfocus);",
+      &text_focus_triggered));
+  EXPECT_TRUE(text_focus_triggered);
+  bool text_keydown_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(textkeydown);",
+      &text_keydown_triggered));
+  EXPECT_TRUE(text_keydown_triggered);
+  bool text_input_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(textinput);",
+      &text_input_triggered));
+  EXPECT_TRUE(text_input_triggered);
+  bool text_change_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(textchange);",
+      &text_change_triggered));
+  EXPECT_TRUE(text_change_triggered);
+  bool text_keyup_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(textkeyup);",
+      &text_keyup_triggered));
+  EXPECT_TRUE(text_keyup_triggered);
+  bool text_blur_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(textblur);",
+      &text_blur_triggered));
+  EXPECT_TRUE(text_blur_triggered);
+
+  // Checks that all the events were fired for the select field.
+  bool select_focus_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(selectfocus);",
+      &select_focus_triggered));
+  EXPECT_TRUE(select_focus_triggered);
+  bool select_input_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(selectinput);",
+      &select_input_triggered));
+  EXPECT_TRUE(select_input_triggered);
+  bool select_change_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(selectchange);",
+      &select_change_triggered));
+  EXPECT_TRUE(select_change_triggered);
+  bool select_blur_triggered;
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      GetRenderViewHost(), "domAutomationController.send(selectblur);",
+      &select_blur_triggered));
+  EXPECT_TRUE(select_blur_triggered);
+}
+
 // Test fails on Linux ASAN, see http://crbug.com/532737
 #if defined(ADDRESS_SANITIZER)
 #define MAYBE_AutofillAfterTranslate DISABLED_AutofillAfterTranslate
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 6b48f2d45..6fa43b2 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -890,7 +890,7 @@
       // returns the default maxlength value.
       TruncateString(&value, input_element->maxLength());
     }
-    field->setValue(value, true);
+    field->setAutofillValue(value);
   }
   // Setting the form might trigger JavaScript, which is capable of
   // destroying the frame.
diff --git a/third_party/WebKit/Source/web/WebFormControlElement.cpp b/third_party/WebKit/Source/web/WebFormControlElement.cpp
index 7dbbea5..64f0c9d 100644
--- a/third_party/WebKit/Source/web/WebFormControlElement.cpp
+++ b/third_party/WebKit/Source/web/WebFormControlElement.cpp
@@ -97,6 +97,26 @@
         unwrap<HTMLSelectElement>()->setValue(value, sendEvents);
 }
 
+void WebFormControlElement::setAutofillValue(const WebString& value)
+{
+    // The input and change events will be sent in setValue.
+    if (isHTMLInputElement(*m_private) || isHTMLTextAreaElement(*m_private)) {
+        if (!focused())
+            unwrap<Element>()->dispatchFocusEvent(nullptr, WebFocusTypeForward, nullptr);
+        unwrap<Element>()->dispatchScopedEvent(Event::createBubble(EventTypeNames::keydown));
+        unwrap<HTMLTextFormControlElement>()->setValue(value, DispatchInputAndChangeEvent);
+        unwrap<Element>()->dispatchScopedEvent(Event::createBubble(EventTypeNames::keyup));
+        if (!focused())
+            unwrap<Element>()->dispatchBlurEvent(nullptr, WebFocusTypeForward, nullptr);
+    } else if (isHTMLSelectElement(*m_private)) {
+        if (!focused())
+            unwrap<Element>()->dispatchFocusEvent(nullptr, WebFocusTypeForward, nullptr);
+        unwrap<HTMLSelectElement>()->setValue(value, true);
+        if (!focused())
+            unwrap<Element>()->dispatchBlurEvent(nullptr, WebFocusTypeForward, nullptr);
+    }
+}
+
 WebString WebFormControlElement::value() const
 {
     if (isHTMLInputElement(*m_private))
diff --git a/third_party/WebKit/public/web/WebFormControlElement.h b/third_party/WebKit/public/web/WebFormControlElement.h
index 504f64fe..0f01e1b 100644
--- a/third_party/WebKit/public/web/WebFormControlElement.h
+++ b/third_party/WebKit/public/web/WebFormControlElement.h
@@ -67,6 +67,9 @@
     // element it finds the option with value matches the given parameter and make the
     // option as the current selection.
     BLINK_EXPORT void setValue(const WebString&, bool sendEvents = false);
+    // Sets the autofilled value for input element, textarea element and select
+    // element and sends a sequence of events to the element.
+    BLINK_EXPORT void setAutofillValue(const WebString&);
     // Returns value of element. For select element, it returns the value of
     // the selected option if present. If no selected option, an empty string
     // is returned. If element doesn't fall into input element, textarea element