[Md Feedback] Add initial data population for dialog.

This change populates the feedback dialog with some initial info, including profile email and current URL, by adding a new WebUI Message Handler for C++ <-> JS messaging. The handler will be build out to support more messaging in the future, e.g. system info, screenshots, and feedback submission.

BUG=632112

Review-Url: https://codereview.chromium.org/2190653003
Cr-Commit-Position: refs/heads/master@{#418977}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index af7034c..96a89bd 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2585,6 +2585,8 @@
       "download/download_shelf.h",
       "download/download_shelf_context_menu.cc",
       "download/download_shelf_context_menu.h",
+      "feedback/feedback_dialog_utils.cc",
+      "feedback/feedback_dialog_utils.h",
       "feedback/feedback_profile_observer.cc",
       "feedback/feedback_profile_observer.h",
       "feedback/show_feedback_page.cc",
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 8426f171..d12e59d 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -183,6 +183,7 @@
       <include name="IDR_FEEDBACK_MANIFEST" file="resources\feedback\manifest.json" type="BINDATA" />
       <if expr="not is_android">
         <include name="IDR_MD_FEEDBACK_FEEDBACK_HTML" file="resources\md_feedback\feedback.html" type="BINDATA" />
+        <include name="IDR_MD_FEEDBACK_FEEDBACK_JS" file="resources\md_feedback\feedback.js" type="BINDATA" />
         <include name="IDR_MD_FEEDBACK_FEEDBACK_CONTAINER_HTML" file="resources\md_feedback\feedback_container.html" type="BINDATA" />
         <include name="IDR_MD_FEEDBACK_FEEDBACK_CONTAINER_JS" file="resources\md_feedback\feedback_container.js" type="BINDATA" />
       </if>
diff --git a/chrome/browser/feedback/feedback_dialog_utils.cc b/chrome/browser/feedback/feedback_dialog_utils.cc
new file mode 100644
index 0000000..56a71db
--- /dev/null
+++ b/chrome/browser/feedback/feedback_dialog_utils.cc
@@ -0,0 +1,66 @@
+// Copyright 2016 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.
+
+#include "chrome/browser/feedback/feedback_dialog_utils.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "content/public/browser/web_contents.h"
+#include "url/gurl.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
+#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "components/signin/core/account_id/account_id.h"
+#endif
+
+namespace chrome {
+
+GURL GetTargetTabUrl(int session_id, int index) {
+  Browser* browser = chrome::FindBrowserWithID(session_id);
+  // Sanity checks.
+  if (!browser || index >= browser->tab_strip_model()->count())
+    return GURL();
+
+  if (index >= 0) {
+    content::WebContents* target_tab =
+        browser->tab_strip_model()->GetWebContentsAt(index);
+    if (target_tab)
+      return target_tab->GetURL();
+  }
+
+  return GURL();
+}
+
+Profile* GetFeedbackProfile(Browser* browser) {
+  Profile* profile =
+      browser ? browser->profile()
+              : ProfileManager::GetLastUsedProfileAllowedByPolicy();
+  if (!profile)
+    return nullptr;
+
+  // We do not want to launch on an OTR profile.
+  profile = profile->GetOriginalProfile();
+  DCHECK(profile);
+
+#if defined(OS_CHROMEOS)
+  // Obtains the display profile ID on which the Feedback window should show.
+  chrome::MultiUserWindowManager* const window_manager =
+      chrome::MultiUserWindowManager::GetInstance();
+  const AccountId display_account_id =
+      window_manager && browser
+          ? window_manager->GetUserPresentingWindow(
+                browser->window()->GetNativeWindow())
+          : EmptyAccountId();
+  if (display_account_id.is_valid())
+    profile = multi_user_util::GetProfileFromAccountId(display_account_id);
+#endif
+  return profile;
+}
+
+}  // namespace chrome
diff --git a/chrome/browser/feedback/feedback_dialog_utils.h b/chrome/browser/feedback/feedback_dialog_utils.h
new file mode 100644
index 0000000..fa7f0f6
--- /dev/null
+++ b/chrome/browser/feedback/feedback_dialog_utils.h
@@ -0,0 +1,24 @@
+// Copyright 2016 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 CHROME_BROWSER_FEEDBACK_FEEDBACK_DIALOG_UTILS_H_
+#define CHROME_BROWSER_FEEDBACK_FEEDBACK_DIALOG_UTILS_H_
+
+class Browser;
+class GURL;
+class Profile;
+
+// Utility functions for the feedback dialog.
+namespace chrome {
+
+// Get the GURL of the active tab when the feedback dialog was invoked, if
+// any.
+GURL GetTargetTabUrl(int session_id, int index);
+
+// Get the profile that should be used to open the feedback dialog.
+Profile* GetFeedbackProfile(Browser* browser);
+
+}  // namespace chrome
+
+#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_DIALOG_UTILS_H_
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc
index 0c04809..d3e0cd8 100644
--- a/chrome/browser/feedback/show_feedback_page.cc
+++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -4,41 +4,13 @@
 
 #include <string>
 
-#include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
+#include "chrome/browser/feedback/feedback_dialog_utils.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
-#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/md_feedback/md_feedback_dialog_controller.h"
 #include "chrome/common/chrome_switches.h"
-#include "components/signin/core/account_id/account_id.h"
-#include "content/public/browser/web_contents.h"
-#include "url/gurl.h"
-
-namespace {
-
-GURL GetTargetTabUrl(int session_id, int index) {
-  Browser* browser = chrome::FindBrowserWithID(session_id);
-  // Sanity checks.
-  if (!browser || index >= browser->tab_strip_model()->count())
-    return GURL();
-
-  if (index >= 0) {
-    content::WebContents* target_tab =
-        browser->tab_strip_model()->GetWebContentsAt(index);
-    if (target_tab)
-      return target_tab->GetURL();
-  }
-
-  return GURL();
-}
-
-}  // namespace
 
 namespace chrome {
 
@@ -51,35 +23,12 @@
                                browser->tab_strip_model()->active_index());
   }
 
-  Profile* profile = NULL;
-  if (browser) {
-    profile = browser->profile();
-  } else {
-    profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
-  }
+  Profile* profile = GetFeedbackProfile(browser);
   if (!profile) {
     LOG(ERROR) << "Cannot invoke feedback: No profile found!";
     return;
   }
 
-  // We do not want to launch on an OTR profile.
-  profile = profile->GetOriginalProfile();
-  DCHECK(profile);
-
-#if defined(OS_CHROMEOS)
-  // Obtains the display profile ID on which the Feedback window should show.
-  chrome::MultiUserWindowManager* const window_manager =
-      chrome::MultiUserWindowManager::GetInstance();
-  const AccountId display_account_id =
-      window_manager && browser
-          ? window_manager->GetUserPresentingWindow(
-                browser->window()->GetNativeWindow())
-          : EmptyAccountId();
-  profile = display_account_id.is_valid()
-                ? multi_user_util::GetProfileFromAccountId(display_account_id)
-                : profile;
-#endif
-
   if (::switches::MdFeedbackEnabled()) {
     MdFeedbackDialogController::GetInstance()->Show(profile);
     return;
diff --git a/chrome/browser/resources/md_feedback/feedback.html b/chrome/browser/resources/md_feedback/feedback.html
index 0ebeca61..665dca7 100644
--- a/chrome/browser/resources/md_feedback/feedback.html
+++ b/chrome/browser/resources/md_feedback/feedback.html
@@ -1,15 +1,17 @@
 <!DOCTYPE HTML>
 <html dir="$i18n{textdirection}" lang="$i18n{language}">
-<html>
 <head>
   <meta charset="utf-8">
 
+  <link rel="import" href="chrome://resources/html/cr.html">
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
   <link rel="import" href="chrome://resources/html/load_time_data.html">
-  <script src="strings.js"></script>
+  <link rel="import" href="chrome://resources/html/util.html">
+  <script src="chrome://feedback/strings.js"></script>
+  <script src="chrome://feedback/feedback.js"></script>
   <link rel="import" href="feedback_container.html">
 </head>
 <body>
-  <feedback-container></feedback-container>
+  <feedback-container id="container"></feedback-container>
 </body>
 </html>
\ No newline at end of file
diff --git a/chrome/browser/resources/md_feedback/feedback.js b/chrome/browser/resources/md_feedback/feedback.js
new file mode 100644
index 0000000..d36aab5
--- /dev/null
+++ b/chrome/browser/resources/md_feedback/feedback.js
@@ -0,0 +1,43 @@
+// Copyright 2016 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.
+
+var Feedback = {};
+
+/**
+ * API invoked by the browser MdFeedbackWebUIMessageHandler to communicate
+ * with this UI.
+ */
+Feedback.UI = class {
+
+  /**
+   * Populates the feedback form with data.
+   *
+   * @param {{email: string|undefined,
+   *          url: string|undefined}} data
+   * Parameters in data:
+   *   email - user's email, if available.
+   *   url - url of the tab the user was on before triggering feedback.
+   */
+  static setData(data) {
+    $('container').email = data['email'];
+    $('container').url = data['url'];
+  }
+};
+
+/** API invoked by this UI to communicate with the browser WebUI message
+ * handler.
+ */
+Feedback.BrowserApi = class {
+  /**
+   * Requests data to initialize the WebUI with.
+   * The data will be returned via Feedback.UI.setData.
+   */
+  static requestData() {
+    chrome.send('requestData');
+  }
+};
+
+window.addEventListener('DOMContentLoaded', function() {
+  Feedback.BrowserApi.requestData();
+});
diff --git a/chrome/browser/resources/md_feedback/feedback_container.html b/chrome/browser/resources/md_feedback/feedback_container.html
index acb0772..aa1596c 100644
--- a/chrome/browser/resources/md_feedback/feedback_container.html
+++ b/chrome/browser/resources/md_feedback/feedback_container.html
@@ -20,8 +20,8 @@
     </div>
     <div>
       <paper-textarea label="$i18n{openEndedLabel}"></paper-textarea>
-      <paper-input label="$i18n{urlLabel}"></paper-input>
-      <paper-input label="$i18n{emailLabel}"></paper-input>
+      <paper-input label="$i18n{urlLabel}" placeholder="[[url]]"></paper-input>
+      <paper-input label="$i18n{emailLabel}" placeholder="[[email]]"></paper-input>
     </div>
     <div>
       <paper-checkbox>$i18n{includeScreenshotLabel}</paper-checkbox>
@@ -30,7 +30,7 @@
       <paper-checkbox>$i18n{sendSystemInfoLabel}</paper-checkbox>
     </div>
     <div>
-      <span>[[getPrivacyNote_()]]</span>
+      <span id="privacyNote"></span>
     </div>
     <div>
       <paper-button>$i18n{cancelButton}</paper-button>
@@ -38,4 +38,4 @@
     </div>
   </template>
   <script src="feedback_container.js"></script>
-</dom-module>
+</dom-module>
\ No newline at end of file
diff --git a/chrome/browser/resources/md_feedback/feedback_container.js b/chrome/browser/resources/md_feedback/feedback_container.js
index 7caa6ab..5b1f8bf2 100644
--- a/chrome/browser/resources/md_feedback/feedback_container.js
+++ b/chrome/browser/resources/md_feedback/feedback_container.js
@@ -8,14 +8,29 @@
 Polymer({
   is: 'feedback-container',
 
-  /**
-   * Retrieves the feedback privacy note text, if it exists. On non-officially
-   * branded builds, the string is not defined.
-   *
-   * @return {string} Privacy note text.
-   */
-  getPrivacyNote_: function() {
-    return loadTimeData.valueExists('privacyNote') ?
-        this.i18n('privacyNote') : '';
+  properties: {
+    /**
+     * The user's email, if available.
+     * @type {string|undefined}
+     */
+    email: {
+      type: String,
+    },
+
+    /**
+     * The URL of the page the user was on before sending feedback.
+     * @type {string|undefined}
+     */
+    url: {
+      type: String,
+    },
+  },
+
+  ready: function() {
+    // Retrieves the feedback privacy note text, if it exists. On non-official
+    // branded builds, the string is not defined.
+    this.$.privacyNote.innerHTML =
+        loadTimeData.valueExists('privacyNote') ?
+            loadTimeData.getString('privacyNote') : '';
   },
 });
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 5906df9..e9c7894 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -914,6 +914,8 @@
       "webui/md_feedback/md_feedback_dialog_controller.h",
       "webui/md_feedback/md_feedback_ui.cc",
       "webui/md_feedback/md_feedback_ui.h",
+      "webui/md_feedback/md_feedback_webui_message_handler.cc",
+      "webui/md_feedback/md_feedback_webui_message_handler.h",
       "webui/md_history_ui.cc",
       "webui/md_history_ui.h",
       "webui/ntp/app_launcher_handler.cc",
diff --git a/chrome/browser/ui/webui/md_feedback/md_feedback_ui.cc b/chrome/browser/ui/webui/md_feedback/md_feedback_ui.cc
index b0ce20a9..8e6724ffa 100644
--- a/chrome/browser/ui/webui/md_feedback/md_feedback_ui.cc
+++ b/chrome/browser/ui/webui/md_feedback/md_feedback_ui.cc
@@ -4,7 +4,8 @@
 
 #include "chrome/browser/ui/webui/md_feedback/md_feedback_ui.h"
 
-#include "chrome/browser/profiles/profile.h"
+// #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
@@ -48,6 +49,9 @@
   html_source->AddLocalizedString("sendSystemInfoLabel",
                                   IDS_MD_FEEDBACK_SEND_SYSTEM_INFO_LABEL);
 
+  // File resources.
+  html_source->AddResourcePath("feedback.js", IDR_MD_FEEDBACK_FEEDBACK_JS);
+
   // Polymer resources.
   html_source->AddResourcePath("feedback_container.html",
         IDR_MD_FEEDBACK_FEEDBACK_CONTAINER_HTML);
@@ -62,12 +66,13 @@
 }  // namespace
 
 MdFeedbackUI::MdFeedbackUI(content::WebUI* web_ui)
-    : content::WebUIController(web_ui) {
+    : content::WebUIController(web_ui), profile_(Profile::FromWebUI(web_ui)) {
   // Set up the chrome://feedback data html_source.
-  Profile* profile = Profile::FromWebUI(web_ui);
   content::WebUIDataSource* html_source =
-      CreateMdFeedbackUIHTMLSource(profile);
-  content::WebUIDataSource::Add(profile, html_source);
+      CreateMdFeedbackUIHTMLSource(profile_);
+  content::WebUIDataSource::Add(profile_, html_source);
+
+  web_ui->AddMessageHandler(new MdFeedbackWebUIMessageHandler(this));
 }
 
 MdFeedbackUI::~MdFeedbackUI() {}
diff --git a/chrome/browser/ui/webui/md_feedback/md_feedback_ui.h b/chrome/browser/ui/webui/md_feedback/md_feedback_ui.h
index 202a6ed..fc71365 100644
--- a/chrome/browser/ui/webui/md_feedback/md_feedback_ui.h
+++ b/chrome/browser/ui/webui/md_feedback/md_feedback_ui.h
@@ -6,18 +6,26 @@
 #define CHROME_BROWSER_UI_WEBUI_MD_FEEDBACK_MD_FEEDBACK_UI_H_
 
 #include "base/macros.h"
+#include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/web_ui_controller.h"
 
 namespace content {
 class BrowserContext;
 }  // namespace content
 
+class MdFeedbackWebUIMessageHandler;
+
 // The WebUI for chrome://feedback.
 class MdFeedbackUI : public content::WebUIController {
  public:
   explicit MdFeedbackUI(content::WebUI* web_ui);
   ~MdFeedbackUI() override;
+
+  Profile* profile() { return profile_; }
+
  private:
+  Profile* profile_;
+
   DISALLOW_COPY_AND_ASSIGN(MdFeedbackUI);
 };
 
diff --git a/chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.cc b/chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.cc
new file mode 100644
index 0000000..4f37a9717
--- /dev/null
+++ b/chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.cc
@@ -0,0 +1,67 @@
+// Copyright 2016 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.
+
+#include "chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "chrome/browser/feedback/feedback_dialog_utils.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/webui/md_feedback/md_feedback_ui.h"
+#include "components/signin/core/browser/signin_manager.h"
+
+namespace {
+
+// Message names.
+constexpr char kRequestData[] = "requestData";
+
+// JS function names.
+constexpr char kSetData[] = "Feedback.UI.setData";
+
+}  // namespace
+
+MdFeedbackWebUIMessageHandler::MdFeedbackWebUIMessageHandler(
+    MdFeedbackUI* md_feedback_ui)
+    : md_feedback_ui_(md_feedback_ui) {
+  DCHECK(md_feedback_ui_);
+}
+
+MdFeedbackWebUIMessageHandler::~MdFeedbackWebUIMessageHandler() {}
+
+void MdFeedbackWebUIMessageHandler::RegisterMessages() {
+  web_ui()->RegisterMessageCallback(
+      kRequestData, base::Bind(&MdFeedbackWebUIMessageHandler::OnRequestData,
+                               base::Unretained(this)));
+}
+
+void MdFeedbackWebUIMessageHandler::OnRequestData(const base::ListValue* args) {
+  DVLOG(1) << "OnRequestData";
+  base::DictionaryValue data;
+
+  Profile* profile = md_feedback_ui_->profile();
+  // Do not launch feedback on an OTR profile.
+  profile = profile->GetOriginalProfile();
+  DCHECK(profile);
+
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfile(profile);
+  DCHECK(signin_manager);
+  data.SetString("email", signin_manager->GetAuthenticatedAccountInfo().email);
+
+  GURL page_url = GURL();
+  Browser* browser = chrome::FindBrowserWithProfile(profile);
+  if (browser) {
+    page_url = chrome::GetTargetTabUrl(
+        browser->session_id().id(), browser->tab_strip_model()->active_index());
+  }
+
+  data.SetString("url", page_url.spec());
+
+  web_ui()->CallJavascriptFunctionUnsafe(kSetData, data);
+}
diff --git a/chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.h b/chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.h
new file mode 100644
index 0000000..6b17db1e
--- /dev/null
+++ b/chrome/browser/ui/webui/md_feedback/md_feedback_webui_message_handler.h
@@ -0,0 +1,32 @@
+// Copyright 2016 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 CHROME_BROWSER_UI_WEBUI_MD_FEEDBACK_MD_FEEDBACK_WEBUI_MESSAGE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_MD_FEEDBACK_MD_FEEDBACK_WEBUI_MESSAGE_HANDLER_H_
+
+#include "base/macros.h"
+#include "content/public/browser/web_ui_message_handler.h"
+
+class MdFeedbackUI;
+
+// The handler for Javascript messages related to the feedback dialog.
+class MdFeedbackWebUIMessageHandler : public content::WebUIMessageHandler {
+ public:
+  explicit MdFeedbackWebUIMessageHandler(MdFeedbackUI* md_feedback_ui);
+  ~MdFeedbackWebUIMessageHandler() override;
+
+ private:
+  // WebUIMessageHandler:
+  void RegisterMessages() override;
+
+  // Handler for a JavaScript message that retrieves data (e.g. user email) to
+  // populate the feedback form.
+  void OnRequestData(const base::ListValue* args);
+
+  MdFeedbackUI* md_feedback_ui_;  // Not owned.
+
+  DISALLOW_COPY_AND_ASSIGN(MdFeedbackWebUIMessageHandler);
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_MD_FEEDBACK_MD_FEEDBACK_WEBUI_MESSAGE_HANDLER_H_