Commit dc2b3be0 authored by apacible's avatar apacible Committed by Commit bot

[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}
parent 5140a41c
...@@ -2585,6 +2585,8 @@ split_static_library("browser") { ...@@ -2585,6 +2585,8 @@ split_static_library("browser") {
"download/download_shelf.h", "download/download_shelf.h",
"download/download_shelf_context_menu.cc", "download/download_shelf_context_menu.cc",
"download/download_shelf_context_menu.h", "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.cc",
"feedback/feedback_profile_observer.h", "feedback/feedback_profile_observer.h",
"feedback/show_feedback_page.cc", "feedback/show_feedback_page.cc",
......
...@@ -183,6 +183,7 @@ ...@@ -183,6 +183,7 @@
<include name="IDR_FEEDBACK_MANIFEST" file="resources\feedback\manifest.json" type="BINDATA" /> <include name="IDR_FEEDBACK_MANIFEST" file="resources\feedback\manifest.json" type="BINDATA" />
<if expr="not is_android"> <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_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_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" /> <include name="IDR_MD_FEEDBACK_FEEDBACK_CONTAINER_JS" file="resources\md_feedback\feedback_container.js" type="BINDATA" />
</if> </if>
......
// 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
// 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_
...@@ -4,41 +4,13 @@ ...@@ -4,41 +4,13 @@
#include <string> #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/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.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.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/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/md_feedback/md_feedback_dialog_controller.h" #include "chrome/browser/ui/webui/md_feedback/md_feedback_dialog_controller.h"
#include "chrome/common/chrome_switches.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 { namespace chrome {
...@@ -51,35 +23,12 @@ void ShowFeedbackPage(Browser* browser, ...@@ -51,35 +23,12 @@ void ShowFeedbackPage(Browser* browser,
browser->tab_strip_model()->active_index()); browser->tab_strip_model()->active_index());
} }
Profile* profile = NULL; Profile* profile = GetFeedbackProfile(browser);
if (browser) {
profile = browser->profile();
} else {
profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
}
if (!profile) { if (!profile) {
LOG(ERROR) << "Cannot invoke feedback: No profile found!"; LOG(ERROR) << "Cannot invoke feedback: No profile found!";
return; 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()) { if (::switches::MdFeedbackEnabled()) {
MdFeedbackDialogController::GetInstance()->Show(profile); MdFeedbackDialogController::GetInstance()->Show(profile);
return; return;
......
<!DOCTYPE HTML> <!DOCTYPE HTML>
<html dir="$i18n{textdirection}" lang="$i18n{language}"> <html dir="$i18n{textdirection}" lang="$i18n{language}">
<html>
<head> <head>
<meta charset="utf-8"> <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="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<link rel="import" href="chrome://resources/html/load_time_data.html"> <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"> <link rel="import" href="feedback_container.html">
</head> </head>
<body> <body>
<feedback-container></feedback-container> <feedback-container id="container"></feedback-container>
</body> </body>
</html> </html>
\ No newline at end of file
// 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();
});
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
</div> </div>
<div> <div>
<paper-textarea label="$i18n{openEndedLabel}"></paper-textarea> <paper-textarea label="$i18n{openEndedLabel}"></paper-textarea>
<paper-input label="$i18n{urlLabel}"></paper-input> <paper-input label="$i18n{urlLabel}" placeholder="[[url]]"></paper-input>
<paper-input label="$i18n{emailLabel}"></paper-input> <paper-input label="$i18n{emailLabel}" placeholder="[[email]]"></paper-input>
</div> </div>
<div> <div>
<paper-checkbox>$i18n{includeScreenshotLabel}</paper-checkbox> <paper-checkbox>$i18n{includeScreenshotLabel}</paper-checkbox>
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<paper-checkbox>$i18n{sendSystemInfoLabel}</paper-checkbox> <paper-checkbox>$i18n{sendSystemInfoLabel}</paper-checkbox>
</div> </div>
<div> <div>
<span>[[getPrivacyNote_()]]</span> <span id="privacyNote"></span>
</div> </div>
<div> <div>
<paper-button>$i18n{cancelButton}</paper-button> <paper-button>$i18n{cancelButton}</paper-button>
......
...@@ -8,14 +8,29 @@ ...@@ -8,14 +8,29 @@
Polymer({ Polymer({
is: 'feedback-container', is: 'feedback-container',
properties: {
/** /**
* Retrieves the feedback privacy note text, if it exists. On non-officially * The user's email, if available.
* branded builds, the string is not defined. * @type {string|undefined}
*
* @return {string} Privacy note text.
*/ */
getPrivacyNote_: function() { email: {
return loadTimeData.valueExists('privacyNote') ? type: String,
this.i18n('privacyNote') : ''; },
/**
* 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') : '';
}, },
}); });
...@@ -914,6 +914,8 @@ split_static_library("ui") { ...@@ -914,6 +914,8 @@ split_static_library("ui") {
"webui/md_feedback/md_feedback_dialog_controller.h", "webui/md_feedback/md_feedback_dialog_controller.h",
"webui/md_feedback/md_feedback_ui.cc", "webui/md_feedback/md_feedback_ui.cc",
"webui/md_feedback/md_feedback_ui.h", "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.cc",
"webui/md_history_ui.h", "webui/md_history_ui.h",
"webui/ntp/app_launcher_handler.cc", "webui/ntp/app_launcher_handler.cc",
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
#include "chrome/browser/ui/webui/md_feedback/md_feedback_ui.h" #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/common/url_constants.h"
#include "chrome/grit/browser_resources.h" #include "chrome/grit/browser_resources.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
...@@ -48,6 +49,9 @@ content::WebUIDataSource* CreateMdFeedbackUIHTMLSource(Profile* profile) { ...@@ -48,6 +49,9 @@ content::WebUIDataSource* CreateMdFeedbackUIHTMLSource(Profile* profile) {
html_source->AddLocalizedString("sendSystemInfoLabel", html_source->AddLocalizedString("sendSystemInfoLabel",
IDS_MD_FEEDBACK_SEND_SYSTEM_INFO_LABEL); IDS_MD_FEEDBACK_SEND_SYSTEM_INFO_LABEL);
// File resources.
html_source->AddResourcePath("feedback.js", IDR_MD_FEEDBACK_FEEDBACK_JS);
// Polymer resources. // Polymer resources.
html_source->AddResourcePath("feedback_container.html", html_source->AddResourcePath("feedback_container.html",
IDR_MD_FEEDBACK_FEEDBACK_CONTAINER_HTML); IDR_MD_FEEDBACK_FEEDBACK_CONTAINER_HTML);
...@@ -62,12 +66,13 @@ content::WebUIDataSource* CreateMdFeedbackUIHTMLSource(Profile* profile) { ...@@ -62,12 +66,13 @@ content::WebUIDataSource* CreateMdFeedbackUIHTMLSource(Profile* profile) {
} // namespace } // namespace
MdFeedbackUI::MdFeedbackUI(content::WebUI* web_ui) 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. // Set up the chrome://feedback data html_source.
Profile* profile = Profile::FromWebUI(web_ui);
content::WebUIDataSource* html_source = content::WebUIDataSource* html_source =
CreateMdFeedbackUIHTMLSource(profile); CreateMdFeedbackUIHTMLSource(profile_);
content::WebUIDataSource::Add(profile, html_source); content::WebUIDataSource::Add(profile_, html_source);
web_ui->AddMessageHandler(new MdFeedbackWebUIMessageHandler(this));
} }
MdFeedbackUI::~MdFeedbackUI() {} MdFeedbackUI::~MdFeedbackUI() {}
...@@ -6,18 +6,26 @@ ...@@ -6,18 +6,26 @@
#define CHROME_BROWSER_UI_WEBUI_MD_FEEDBACK_MD_FEEDBACK_UI_H_ #define CHROME_BROWSER_UI_WEBUI_MD_FEEDBACK_MD_FEEDBACK_UI_H_
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_controller.h"
namespace content { namespace content {
class BrowserContext; class BrowserContext;
} // namespace content } // namespace content
class MdFeedbackWebUIMessageHandler;
// The WebUI for chrome://feedback. // The WebUI for chrome://feedback.
class MdFeedbackUI : public content::WebUIController { class MdFeedbackUI : public content::WebUIController {
public: public:
explicit MdFeedbackUI(content::WebUI* web_ui); explicit MdFeedbackUI(content::WebUI* web_ui);
~MdFeedbackUI() override; ~MdFeedbackUI() override;
Profile* profile() { return profile_; }
private: private:
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(MdFeedbackUI); DISALLOW_COPY_AND_ASSIGN(MdFeedbackUI);
}; };
......
// 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);
}
// 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_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment