[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_