Add candidatewindow* events related IPCs

These IPCs correspond to Javascript IME API events
(oncandidatewindow*) defined in
https://dvcs.w3.org/hg/ime-api/raw-file/8c061ee19f99/Overview.html#inputmethodcontext-interface

They will fire when IME candidate window changes its appearance.

The Blink side of the change is already checked in:
https://src.chromium.org/viewvc/blink?revision=161139&view=revision

This is the Chromium part of sending IPCs to renderer and
a test for both Chromium and Blink code path, which is not
covered by blink r161139.

The whole change FYI is worked on at
https://codereview.chromium.org/80583002/
and other CLs (to generate actual events from IMEs etc.)
will follow.

BUG=238585
TEST=content_browsertests --gtest_filter="RenderViewImplTest.SendCandidateWindowEvents"

Review URL: https://codereview.chromium.org/84963003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238282 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 337180d..9cb8922 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1308,6 +1308,18 @@
   Send(new ViewMsg_SetInputMethodActive(GetRoutingID(), activate));
 }
 
+void RenderWidgetHostImpl::CandidateWindowShown() {
+  Send(new ViewMsg_CandidateWindowShown(GetRoutingID()));
+}
+
+void RenderWidgetHostImpl::CandidateWindowUpdated() {
+  Send(new ViewMsg_CandidateWindowUpdated(GetRoutingID()));
+}
+
+void RenderWidgetHostImpl::CandidateWindowHidden() {
+  Send(new ViewMsg_CandidateWindowHidden(GetRoutingID()));
+}
+
 void RenderWidgetHostImpl::ImeSetComposition(
     const string16& text,
     const std::vector<blink::WebCompositionUnderline>& underlines,
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 36a63e3..66e2e9a 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -312,6 +312,11 @@
   // display input method windows under the cursor.)
   void SetInputMethodActive(bool activate);
 
+  // Notifies the renderer changes of IME candidate window state.
+  void CandidateWindowShown();
+  void CandidateWindowUpdated();
+  void CandidateWindowHidden();
+
   // Update the composition node of the renderer (or WebKit).
   // WebKit has a special node (a composition node) for input method to change
   // its text without affecting any other DOM nodes. When the input method
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 81bea27..7c9c507 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2386,12 +2386,15 @@
 }
 
 void RenderWidgetHostViewAura::OnCandidateWindowShown() {
+  host_->CandidateWindowShown();
 }
 
 void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
+  host_->CandidateWindowUpdated();
 }
 
 void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
+  host_->CandidateWindowHidden();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 0dc7ab8..2e8d41a2 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1105,6 +1105,11 @@
 IPC_MESSAGE_ROUTED1(ViewMsg_SetInputMethodActive,
                     bool /* is_active */)
 
+// IME API oncandidatewindow* events for InputMethodContext.
+IPC_MESSAGE_ROUTED0(ViewMsg_CandidateWindowShown)
+IPC_MESSAGE_ROUTED0(ViewMsg_CandidateWindowUpdated)
+IPC_MESSAGE_ROUTED0(ViewMsg_CandidateWindowHidden)
+
 // This message sends a string being composed with an input method.
 IPC_MESSAGE_ROUTED4(
     ViewMsg_ImeSetComposition,
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index c43a82f..a95d20b 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -2112,4 +2112,42 @@
             UTF16ToASCII(web_frame->contentAsText(kMaxOutputCharacters)));
 }
 
+// Tests if IME API's candidatewindow* events sent from browser are handled
+// in renderer.
+TEST_F(RenderViewImplTest, SendCandidateWindowEvents) {
+  // Sends an HTML with an <input> element and scripts to the renderer.
+  // The script handles all 3 of candidatewindow* events for an
+  // InputMethodContext object and once it received 'show', 'update', 'hide'
+  // should appear in the result div.
+  LoadHTML("<input id='test'>"
+           "<div id='result'>Result: </div>"
+           "<script>"
+           "window.onload = function() {"
+           "  var result = document.getElementById('result');"
+           "  var test = document.getElementById('test');"
+           "  test.focus();"
+           "  var context = test.inputMethodContext;"
+           "  if (context) {"
+           "    context.oncandidatewindowshow = function() {"
+           "        result.innerText += 'show'; };"
+           "    context.oncandidatewindowupdate = function(){"
+           "        result.innerText += 'update'; };"
+           "    context.oncandidatewindowhide = function(){"
+           "        result.innerText += 'hide'; };"
+           "  }"
+           "};"
+           "</script>");
+
+  // Fire candidatewindow events.
+  view()->OnCandidateWindowShown();
+  view()->OnCandidateWindowUpdated();
+  view()->OnCandidateWindowHidden();
+
+  // Retrieve the content and check if it is expected.
+  const int kMaxOutputCharacters = 50;
+  std::string output = UTF16ToUTF8(
+      GetMainFrame()->contentAsText(kMaxOutputCharacters));
+  EXPECT_EQ(output, "\nResult:showupdatehide");
+}
+
 }  // namespace content
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index b5acbab..f3c7cf08 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -795,6 +795,7 @@
   FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, TextInputTypeWithPepper);
   FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest,
                            MessageOrderInDidChangeSelection);
+  FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, SendCandidateWindowEvents);
   FRIEND_TEST_ALL_PREFIXES(SuppressErrorPageTest, Suppresses);
   FRIEND_TEST_ALL_PREFIXES(SuppressErrorPageTest, DoesNotSuppress);
 
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 9c8cf7d..24b5fa6 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -588,6 +588,10 @@
     IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck)
     IPC_MESSAGE_HANDLER(ViewMsg_SwapBuffers_ACK, OnSwapBuffersComplete)
     IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive)
+    IPC_MESSAGE_HANDLER(ViewMsg_CandidateWindowShown, OnCandidateWindowShown)
+    IPC_MESSAGE_HANDLER(ViewMsg_CandidateWindowUpdated,
+                        OnCandidateWindowUpdated)
+    IPC_MESSAGE_HANDLER(ViewMsg_CandidateWindowHidden, OnCandidateWindowHidden)
     IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
     IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition)
     IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnPaintAtSize)
@@ -2079,6 +2083,18 @@
   input_method_is_active_ = is_active;
 }
 
+void RenderWidget::OnCandidateWindowShown() {
+  webwidget_->didShowCandidateWindow();
+}
+
+void RenderWidget::OnCandidateWindowUpdated() {
+  webwidget_->didUpdateCandidateWindow();
+}
+
+void RenderWidget::OnCandidateWindowHidden() {
+  webwidget_->didHideCandidateWindow();
+}
+
 void RenderWidget::OnImeSetComposition(
     const string16& text,
     const std::vector<WebCompositionUnderline>& underlines,
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 9cc1b98..61291042 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -347,6 +347,9 @@
   void OnUpdateVideoAck(int32 video_id);
   void OnRequestMoveAck();
   void OnSetInputMethodActive(bool is_active);
+  void OnCandidateWindowShown();
+  void OnCandidateWindowUpdated();
+  void OnCandidateWindowHidden();
   virtual void OnImeSetComposition(
       const string16& text,
       const std::vector<blink::WebCompositionUnderline>& underlines,