OnionSoup: Migrate IPC message handler to Mojo in Android's RendererDateTimePicker

As a first step to moving content/renderer/renderer_date_time_picker to Blink,
this CL migrates IPC message handler to Mojo in RendererDateTimePicker first.
Major changes are as below,

  - Introduce date_time_picker.mojom with DateTimePicker interface.
  - Introduce DateTimeDialogValue struct in date_time_picker.mojom.
  - Move DateTimeSuggestion struct to date_time_picker.mojom.
  - Remove all IPC messages regarding DateTimePicker
    (content::DateTimeSuggestion and ViewHostMsg_DateTimeDialogValue_Params)

The following CL will move the date_time_picker Mojo to Blink.

Bug: 950157
Change-Id: If3c2f7fd2c0e71cd485c0372efbcff0348ffca9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1564361
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Reviewed-by: Kentaro Hara <[email protected]>
Commit-Queue: Gyuyoung Kim <[email protected]>
Cr-Commit-Position: refs/heads/master@{#653861}
diff --git a/content/browser/android/date_time_chooser_android.cc b/content/browser/android/date_time_chooser_android.cc
index 5d0f044..c26d1bf 100644
--- a/content/browser/android/date_time_chooser_android.cc
+++ b/content/browser/android/date_time_chooser_android.cc
@@ -10,8 +10,9 @@
 #include "base/android/jni_string.h"
 #include "base/i18n/char_iterator.h"
 #include "base/i18n/unicodestring.h"
-#include "content/common/date_time_suggestion.h"
-#include "content/common/view_messages.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "jni/DateTimeChooserAndroid_jni.h"
 #include "third_party/icu/source/common/unicode/uchar.h"
@@ -45,62 +46,84 @@
 namespace content {
 
 // DateTimeChooserAndroid implementation
-DateTimeChooserAndroid::DateTimeChooserAndroid()
-  : host_(NULL) {
+DateTimeChooserAndroid::DateTimeChooserAndroid(WebContentsImpl* web_contents)
+    : content::WebContentsObserver(web_contents),
+      date_time_picker_binding_(this) {
+  registry_.AddInterface(
+      base::BindRepeating(&DateTimeChooserAndroid::OnDateTimePickerRequest,
+                          base::Unretained(this)));
 }
 
 DateTimeChooserAndroid::~DateTimeChooserAndroid() {
 }
 
-void DateTimeChooserAndroid::ReplaceDateTime(JNIEnv* env,
-                                             const JavaRef<jobject>&,
-                                             jdouble value) {
-  host_->Send(new ViewMsg_ReplaceDateTime(host_->GetRoutingID(), value));
+void DateTimeChooserAndroid::OnDateTimePickerRequest(
+    mojom::DateTimePickerRequest request) {
+  // Disconnect the previous picker first.
+  date_time_picker_binding_.Close();
+
+  date_time_picker_binding_.Bind(std::move(request));
 }
 
-void DateTimeChooserAndroid::CancelDialog(JNIEnv* env,
-                                          const JavaRef<jobject>&) {
-  host_->Send(new ViewMsg_CancelDateTimeDialog(host_->GetRoutingID()));
-}
-
-void DateTimeChooserAndroid::ShowDialog(
-    gfx::NativeWindow native_window,
-    RenderViewHost* host,
-    ui::TextInputType dialog_type,
-    double dialog_value,
-    double min,
-    double max,
-    double step,
-    const std::vector<DateTimeSuggestion>& suggestions) {
-  host_ = host;
-
+void DateTimeChooserAndroid::OpenDateTimeDialog(
+    mojom::DateTimeDialogValuePtr value,
+    OpenDateTimeDialogCallback callback) {
   JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobjectArray> suggestions_array;
 
-  if (suggestions.size() > 0) {
-    suggestions_array =
-        Java_DateTimeChooserAndroid_createSuggestionsArray(env,
-                                                           suggestions.size());
-    for (size_t i = 0; i < suggestions.size(); ++i) {
-      const content::DateTimeSuggestion& suggestion = suggestions[i];
+  if (open_date_time_response_callback_) {
+    date_time_picker_binding_.ReportBadMessage(
+        "DateTimeChooserAndroid: Previous picker's binding isn't closed.");
+    return;
+  }
+  open_date_time_response_callback_ = std::move(callback);
+
+  ScopedJavaLocalRef<jobjectArray> suggestions_array;
+  if (value->suggestions.size() > 0) {
+    suggestions_array = Java_DateTimeChooserAndroid_createSuggestionsArray(
+        env, value->suggestions.size());
+    for (size_t i = 0; i < value->suggestions.size(); ++i) {
+      const mojom::DateTimeSuggestionPtr suggestion =
+          std::move(value->suggestions[i]);
       ScopedJavaLocalRef<jstring> localized_value = ConvertUTF16ToJavaString(
-          env, SanitizeSuggestionString(suggestion.localized_value));
+          env, SanitizeSuggestionString(
+                   base::ASCIIToUTF16(suggestion->localized_value)));
       ScopedJavaLocalRef<jstring> label = ConvertUTF16ToJavaString(
-          env, SanitizeSuggestionString(suggestion.label));
+          env, SanitizeSuggestionString(base::ASCIIToUTF16(suggestion->label)));
       Java_DateTimeChooserAndroid_setDateTimeSuggestionAt(
-          env, suggestions_array, i, suggestion.value, localized_value, label);
+          env, suggestions_array, i, suggestion->value, localized_value, label);
     }
   }
 
+  gfx::NativeWindow native_window = web_contents()->GetTopLevelNativeWindow();
+
   if (native_window && !(native_window->GetJavaObject()).is_null()) {
     j_date_time_chooser_.Reset(
         Java_DateTimeChooserAndroid_createDateTimeChooser(
             env, native_window->GetJavaObject(),
-            reinterpret_cast<intptr_t>(this), dialog_type, dialog_value, min,
-            max, step, suggestions_array));
+            reinterpret_cast<intptr_t>(this), value->dialog_type,
+            value->dialog_value, value->minimum, value->maximum, value->step,
+            suggestions_array));
   }
   if (j_date_time_chooser_.is_null())
-    ReplaceDateTime(env, j_date_time_chooser_, dialog_value);
+    std::move(open_date_time_response_callback_).Run(true, value->dialog_value);
+}
+
+void DateTimeChooserAndroid::ReplaceDateTime(JNIEnv* env,
+                                             const JavaRef<jobject>&,
+                                             jdouble value) {
+  std::move(open_date_time_response_callback_).Run(true, value);
+}
+
+void DateTimeChooserAndroid::CancelDialog(JNIEnv* env,
+                                          const JavaRef<jobject>&) {
+  std::move(open_date_time_response_callback_).Run(false, 0.0);
+}
+
+void DateTimeChooserAndroid::OnInterfaceRequestFromFrame(
+    content::RenderFrameHost* render_frame_host,
+    const std::string& interface_name,
+    mojo::ScopedMessagePipeHandle* interface_pipe) {
+  registry_.TryBindInterface(interface_name, interface_pipe);
 }
 
 }  // namespace content
diff --git a/content/browser/android/date_time_chooser_android.h b/content/browser/android/date_time_chooser_android.h
index f5da0e6..1886684 100644
--- a/content/browser/android/date_time_chooser_android.h
+++ b/content/browser/android/date_time_chooser_android.h
@@ -11,33 +11,34 @@
 
 #include "base/android/jni_weak_ref.h"
 #include "base/macros.h"
+#include "content/common/date_time_picker.mojom.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
 #include "ui/base/ime/text_input_type.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace content {
 
-class RenderViewHost;
-struct DateTimeSuggestion;
+class WebContentsImpl;
+class RenderFrameHost;
 
 // Android implementation for DateTimeChooser dialogs.
-class DateTimeChooserAndroid {
+class DateTimeChooserAndroid : public mojom::DateTimePicker,
+                               public WebContentsObserver {
  public:
-  DateTimeChooserAndroid();
-  ~DateTimeChooserAndroid();
+  explicit DateTimeChooserAndroid(WebContentsImpl* web_contents);
+  ~DateTimeChooserAndroid() override;
 
-  // DateTimeChooser implementation:
-  // Shows the dialog. |dialog_value| is the date/time value converted to a
+  void OnDateTimePickerRequest(mojom::DateTimePickerRequest request);
+
+  // content::mojom::DateTimePicker implementation:
+  // Shows the dialog. |value| is the date/time value converted to a
   // number as defined in HTML. (See blink::InputType::parseToNumber())
-  void ShowDialog(gfx::NativeWindow native_window,
-                  RenderViewHost* host,
-                  ui::TextInputType dialog_type,
-                  double dialog_value,
-                  double min,
-                  double max,
-                  double step,
-                  const std::vector<DateTimeSuggestion>& suggestions);
+  void OpenDateTimeDialog(mojom::DateTimeDialogValuePtr value,
+                          OpenDateTimeDialogCallback callback) override;
 
-  // Replaces the current value
+  // Replaces the current value.
   void ReplaceDateTime(JNIEnv* env,
                        const base::android::JavaRef<jobject>&,
                        jdouble value);
@@ -45,11 +46,21 @@
   // Closes the dialog without propagating any changes.
   void CancelDialog(JNIEnv* env, const base::android::JavaRef<jobject>&);
 
+  // WebContentsObserver overrides:
+  void OnInterfaceRequestFromFrame(
+      content::RenderFrameHost* render_frame_host,
+      const std::string& interface_name,
+      mojo::ScopedMessagePipeHandle* interface_pipe) override;
+
  private:
-  RenderViewHost* host_;
+  OpenDateTimeDialogCallback open_date_time_response_callback_;
 
   base::android::ScopedJavaGlobalRef<jobject> j_date_time_chooser_;
 
+  mojo::Binding<mojom::DateTimePicker> date_time_picker_binding_;
+
+  service_manager::BinderRegistry registry_;
+
   DISALLOW_COPY_AND_ASSIGN(DateTimeChooserAndroid);
 };
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index d43b70a..12e572a5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -864,9 +864,6 @@
     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestPpapiBrokerPermission,
                         OnRequestPpapiBrokerPermission)
 #endif
-#if defined(OS_ANDROID)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_OpenDateTimeDialog, OnOpenDateTimeDialog)
-#endif
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -2105,7 +2102,7 @@
   manifest_manager_host_.reset(new ManifestManagerHost(this));
 
 #if defined(OS_ANDROID)
-  date_time_chooser_.reset(new DateTimeChooserAndroid());
+  date_time_chooser_.reset(new DateTimeChooserAndroid(this));
 #endif
 
   // BrowserPluginGuest::Init needs to be called after this WebContents has
@@ -4834,16 +4831,6 @@
   page_importance_signals_ = signals;
 }
 
-#if defined(OS_ANDROID)
-void WebContentsImpl::OnOpenDateTimeDialog(
-    RenderViewHostImpl* source,
-    const ViewHostMsg_DateTimeDialogValue_Params& value) {
-  date_time_chooser_->ShowDialog(
-      GetTopLevelNativeWindow(), source, value.dialog_type, value.dialog_value,
-      value.minimum, value.maximum, value.step, value.suggestions);
-}
-#endif
-
 void WebContentsImpl::OnDomOperationResponse(RenderFrameHostImpl* source,
                                              const std::string& json_string) {
   // TODO(nick, lukasza): The notification below should probably be updated to
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 12fad99..22085cc 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -74,8 +74,6 @@
 #include "content/public/browser/android/child_process_importance.h"
 #endif
 
-struct ViewHostMsg_DateTimeDialogValue_Params;
-
 namespace service_manager {
 class InterfaceProvider;
 }
@@ -1251,11 +1249,6 @@
                                    const std::string& protocol,
                                    const GURL& url,
                                    bool user_gesture);
-#if defined(OS_ANDROID)
-  void OnOpenDateTimeDialog(
-      RenderViewHostImpl* source,
-      const ViewHostMsg_DateTimeDialogValue_Params& value);
-#endif
   void OnDomOperationResponse(RenderFrameHostImpl* source,
                               const std::string& json_string);
   void OnUpdatePageImportanceSignals(RenderFrameHostImpl* source,
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 05784fc..f7d55082 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -92,7 +92,6 @@
     "cursors/webcursor_aurax11.cc",
     "cursors/webcursor_mac.mm",
     "cursors/webcursor_ozone.cc",
-    "date_time_suggestion.h",
     "dom_storage/dom_storage_map.cc",
     "dom_storage/dom_storage_map.h",
     "dom_storage/dom_storage_messages.h",
@@ -502,6 +501,10 @@
     ]
   }
 
+  if (is_android) {
+    sources += [ "date_time_picker.mojom" ]
+  }
+
   enabled_features = []
   if (enable_ipc_logging) {
     enabled_features += [ "ipc_logging" ]
diff --git a/content/common/date_time_picker.mojom b/content/common/date_time_picker.mojom
new file mode 100644
index 0000000..6dab38b
--- /dev/null
+++ b/content/common/date_time_picker.mojom
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "ui/base/ime/mojo/ime_types.mojom";
+
+struct DateTimeSuggestion {
+  // The date/time value represented as a double.
+  double value;
+
+  // The localized value to be shown to the user.
+  string localized_value;
+
+  // The label for the suggestion.
+  string label;
+};
+
+struct DateTimeDialogValue {
+  ui.mojom.TextInputType dialog_type;
+  double dialog_value;
+  double minimum;
+  double maximum;
+  double step;
+  array<DateTimeSuggestion> suggestions;
+};
+
+// Interface exposed by the browser to the renderer.
+interface DateTimePicker {
+  // Requires for opening a date/time dialog, and then |dialog_value| is
+  // returned to replace a date/time input field.
+  [EnableIf=is_android]
+  OpenDateTimeDialog(DateTimeDialogValue value) =>
+      (bool success, double dialog_value);
+};
diff --git a/content/common/date_time_suggestion.h b/content/common/date_time_suggestion.h
deleted file mode 100644
index ce35430c..0000000
--- a/content/common/date_time_suggestion.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_DATE_TIME_SUGGESTION_H_
-#define CONTENT_COMMON_DATE_TIME_SUGGESTION_H_
-
-#include <vector>
-
-#include "base/strings/string16.h"
-#include "content/common/content_export.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace content {
-
-// Container for information about datalist suggestion for the date/time input
-// control. Keep in sync with DateTimeSuggestion.java
-struct CONTENT_EXPORT DateTimeSuggestion {
-  DateTimeSuggestion() {}
-
-  // The date/time value represented as a double.
-  double value;
-  // The localized value to be shown to the user.
-  base::string16 localized_value;
-  // The label for the suggestion.
-  base::string16 label;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_COMMON_DATE_TIME_SUGGESTION_H_
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc
index a17bd78..35bc65d 100644
--- a/content/common/swapped_out_messages.cc
+++ b/content/common/swapped_out_messages.cc
@@ -21,7 +21,6 @@
     case FrameHostMsg_RenderProcessGone::ID:
     case ViewHostMsg_ClosePage_ACK::ID:
     case ViewHostMsg_Focus::ID:
-    case ViewHostMsg_OpenDateTimeDialog::ID:
     case ViewHostMsg_ShowFullscreenWidget::ID:
     case ViewHostMsg_ShowWidget::ID:
     case ViewHostMsg_UpdateTargetURL::ID:
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 7a83198..31a3cfe4 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -25,7 +25,6 @@
 #include "components/viz/common/resources/shared_bitmap.h"
 #include "content/common/content_export.h"
 #include "content/common/content_param_traits.h"
-#include "content/common/date_time_suggestion.h"
 #include "content/common/frame_replication_state.h"
 #include "content/common/navigation_gesture.h"
 #include "content/public/common/common_param_traits.h"
@@ -104,33 +103,8 @@
   IPC_STRUCT_TRAITS_MEMBER(submenu)
 IPC_STRUCT_TRAITS_END()
 
-IPC_STRUCT_TRAITS_BEGIN(content::DateTimeSuggestion)
-  IPC_STRUCT_TRAITS_MEMBER(value)
-  IPC_STRUCT_TRAITS_MEMBER(localized_value)
-  IPC_STRUCT_TRAITS_MEMBER(label)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_BEGIN(ViewHostMsg_DateTimeDialogValue_Params)
-  IPC_STRUCT_MEMBER(ui::TextInputType, dialog_type)
-  IPC_STRUCT_MEMBER(double, dialog_value)
-  IPC_STRUCT_MEMBER(double, minimum)
-  IPC_STRUCT_MEMBER(double, maximum)
-  IPC_STRUCT_MEMBER(double, step)
-  IPC_STRUCT_MEMBER(std::vector<content::DateTimeSuggestion>, suggestions)
-IPC_STRUCT_END()
-
 // Messages sent from the browser to the renderer.
 
-#if defined(OS_ANDROID)
-// Tells the renderer to cancel an opened date/time dialog.
-IPC_MESSAGE_ROUTED0(ViewMsg_CancelDateTimeDialog)
-
-// Replaces a date time input field.
-IPC_MESSAGE_ROUTED1(ViewMsg_ReplaceDateTime,
-                    double /* dialog_value */)
-
-#endif
-
 // Make the RenderWidget background transparent or opaque.
 IPC_MESSAGE_ROUTED1(ViewMsg_SetBackgroundOpaque, bool /* opaque */)
 
@@ -296,10 +270,6 @@
 IPC_MESSAGE_ROUTED1(ViewHostMsg_TakeFocus,
                     bool /* reverse */)
 
-// Required for opening a date/time dialog
-IPC_MESSAGE_ROUTED1(ViewHostMsg_OpenDateTimeDialog,
-                    ViewHostMsg_DateTimeDialogValue_Params /* value */)
-
 // Sent when the renderer changes its page scale factor.
 IPC_MESSAGE_ROUTED1(ViewHostMsg_PageScaleFactorChanged,
                     float /* page_scale_factor */)
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc
index a1fa37e0..efb4a17 100644
--- a/content/public/app/content_browser_manifest.cc
+++ b/content/public/app/content_browser_manifest.cc
@@ -236,6 +236,7 @@
                   "content.mojom.InputInjector",
                   "content.mojom.RendererAudioInputStreamFactory",
                   "content.mojom.RendererAudioOutputStreamFactory",
+                  "content.mojom.DateTimePicker",
                   "device.mojom.GamepadMonitor",
                   "device.mojom.Geolocation",
                   "device.mojom.NFC",
diff --git a/content/renderer/android/renderer_date_time_picker.cc b/content/renderer/android/renderer_date_time_picker.cc
index d5371437..2e3b96cc 100644
--- a/content/renderer/android/renderer_date_time_picker.cc
+++ b/content/renderer/android/renderer_date_time_picker.cc
@@ -7,8 +7,6 @@
 #include <stddef.h>
 
 #include "base/strings/string_util.h"
-#include "content/common/date_time_suggestion.h"
-#include "content/common/view_messages.h"
 #include "content/renderer/render_view_impl.h"
 #include "third_party/blink/public/web/web_date_time_chooser_completion.h"
 #include "third_party/blink/public/web/web_date_time_chooser_params.h"
@@ -18,22 +16,26 @@
 
 using blink::WebString;
 
+namespace mojo {
+
+template <>
+struct TypeConverter<::content::mojom::DateTimeSuggestionPtr,
+                     ::blink::WebDateTimeSuggestion> {
+  static content::mojom::DateTimeSuggestionPtr Convert(
+      const blink::WebDateTimeSuggestion& input) {
+    content::mojom::DateTimeSuggestionPtr output =
+        content::mojom::DateTimeSuggestion::New();
+    output->value = input.value;
+    output->localized_value = input.localized_value.Ascii();
+    output->label = input.label.Ascii();
+    return output;
+  }
+};
+
+}  // namespace mojo
+
 namespace content {
 
-namespace {
-
-// Converts a |blink::WebDateTimeSuggestion| structure to |DateTimeSuggestion|.
-DateTimeSuggestion ToDateTimeSuggestion(
-    const blink::WebDateTimeSuggestion& suggestion) {
-  DateTimeSuggestion result;
-  result.value = suggestion.value;
-  result.localized_value = suggestion.localized_value.Utf16();
-  result.label = suggestion.label.Utf16();
-  return result;
-}
-
-}  // namespace
-
 static ui::TextInputType ToTextInputType(int type) {
   switch (type) {
     case blink::kWebDateTimeInputTypeDate:
@@ -66,44 +68,45 @@
     blink::WebDateTimeChooserCompletion* completion)
     : RenderViewObserver(sender),
       chooser_params_(params),
-      chooser_completion_(completion) {
-}
+      chooser_completion_(completion) {}
 
-RendererDateTimePicker::~RendererDateTimePicker() {
-}
+RendererDateTimePicker::~RendererDateTimePicker() {}
 
-bool RendererDateTimePicker::Open() {
-  ViewHostMsg_DateTimeDialogValue_Params message;
-  message.dialog_type = ToTextInputType(chooser_params_.type);
-  message.dialog_value = chooser_params_.double_value;
-  message.minimum = chooser_params_.minimum;
-  message.maximum = chooser_params_.maximum;
-  message.step = chooser_params_.step;
+void RendererDateTimePicker::Open() {
+  mojom::DateTimeDialogValuePtr date_time_dialog_value =
+      mojom::DateTimeDialogValue::New();
+  date_time_dialog_value->dialog_type = ToTextInputType(chooser_params_.type);
+  date_time_dialog_value->dialog_value = chooser_params_.double_value;
+  date_time_dialog_value->minimum = chooser_params_.minimum;
+  date_time_dialog_value->maximum = chooser_params_.maximum;
+  date_time_dialog_value->step = chooser_params_.step;
   for (size_t i = 0; i < chooser_params_.suggestions.size(); i++) {
-    message.suggestions.push_back(
-        ToDateTimeSuggestion(chooser_params_.suggestions[i]));
+    date_time_dialog_value->suggestions.push_back(
+        mojo::ConvertTo<mojom::DateTimeSuggestionPtr>(
+            chooser_params_.suggestions[i]));
   }
-  return Send(new ViewHostMsg_OpenDateTimeDialog(routing_id(), message));
+
+  auto response_callback = base::BindOnce(
+      &RendererDateTimePicker::ResponseHandler, base::Unretained(this));
+  GetDateTimePicker()->OpenDateTimeDialog(std::move(date_time_dialog_value),
+                                          std::move(response_callback));
 }
 
-bool RendererDateTimePicker::OnMessageReceived(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(RendererDateTimePicker, message)
-    IPC_MESSAGE_HANDLER(ViewMsg_ReplaceDateTime, OnReplaceDateTime)
-    IPC_MESSAGE_HANDLER(ViewMsg_CancelDateTimeDialog, OnCancel)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
+void RendererDateTimePicker::ResponseHandler(bool success,
+                                             double dialog_value) {
+  if (success)
+    ReplaceDateTime(dialog_value);
+  else
+    Cancel();
 }
 
-void RendererDateTimePicker::OnReplaceDateTime(double value) {
+void RendererDateTimePicker::ReplaceDateTime(double value) {
   if (chooser_completion_)
     chooser_completion_->DidChooseValue(value);
   static_cast<RenderViewImpl*>(render_view())->DismissDateTimeDialog();
 }
 
-void RendererDateTimePicker::OnCancel() {
+void RendererDateTimePicker::Cancel() {
   if (chooser_completion_)
     chooser_completion_->DidCancelChooser();
   static_cast<RenderViewImpl*>(render_view())->DismissDateTimeDialog();
@@ -113,4 +116,12 @@
   delete this;
 }
 
+mojom::DateTimePicker* RendererDateTimePicker::GetDateTimePicker() {
+  if (!date_time_picker_) {
+    render_view()->GetMainRenderFrame()->GetRemoteInterfaces()->GetInterface(
+        &date_time_picker_);
+  }
+  return date_time_picker_.get();
+}
+
 }  // namespace content
diff --git a/content/renderer/android/renderer_date_time_picker.h b/content/renderer/android/renderer_date_time_picker.h
index 583619f..f0464d6b 100644
--- a/content/renderer/android/renderer_date_time_picker.h
+++ b/content/renderer/android/renderer_date_time_picker.h
@@ -6,6 +6,7 @@
 #define CONTENT_RENDERER_ANDROID_RENDERER_DATE_TIME_PICKER_H_
 
 #include "base/macros.h"
+#include "content/common/date_time_picker.mojom.h"
 #include "content/public/renderer/render_view_observer.h"
 #include "third_party/blink/public/web/web_date_time_chooser_params.h"
 
@@ -18,22 +19,26 @@
 
 class RendererDateTimePicker : public RenderViewObserver {
  public:
-  RendererDateTimePicker(
-      RenderViewImpl* sender,
-      const blink::WebDateTimeChooserParams& params,
-      blink::WebDateTimeChooserCompletion* completion);
+  RendererDateTimePicker(RenderViewImpl* sender,
+                         const blink::WebDateTimeChooserParams& params,
+                         blink::WebDateTimeChooserCompletion* completion);
   ~RendererDateTimePicker() override;
 
-  bool Open();
+  void Open();
 
  private:
-  void OnReplaceDateTime(double value);
-  void OnCancel();
+  void ResponseHandler(bool success, double dialog_value);
+
+  void ReplaceDateTime(double value);
+  void Cancel();
 
   // RenderViewObserver
-  bool OnMessageReceived(const IPC::Message& message) override;
   void OnDestruct() override;
 
+  mojom::DateTimePicker* GetDateTimePicker();
+
+  mojom::DateTimePickerPtr date_time_picker_;
+
   blink::WebDateTimeChooserParams chooser_params_;
   blink::WebDateTimeChooserCompletion* chooser_completion_;  // Not owned by us
 
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 3e328da..6f5469e 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -2183,7 +2183,8 @@
     return false;
   date_time_picker_client_.reset(
       new RendererDateTimePicker(this, params, completion));
-  return date_time_picker_client_->Open();
+  date_time_picker_client_->Open();
+  return true;
 }
 
 void RenderViewImpl::DismissDateTimeDialog() {