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") {
"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",
......
......@@ -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>
......
// 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 @@
#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 @@ void ShowFeedbackPage(Browser* browser,
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;
......
<!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
// 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 @@
</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
......@@ -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') : '';
},
});
......@@ -914,6 +914,8 @@ split_static_library("ui") {
"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",
......
......@@ -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 @@ content::WebUIDataSource* CreateMdFeedbackUIHTMLSource(Profile* profile) {
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 @@ content::WebUIDataSource* CreateMdFeedbackUIHTMLSource(Profile* profile) {
} // 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() {}
......@@ -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);
};
......
// 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