summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrkc@google.com <rkc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-19 17:42:20 +0000
committerrkc@google.com <rkc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-19 17:42:20 +0000
commit74a9f9f48c5832f548368eb8b43933f6b2a10e60 (patch)
tree5067464449bbb6725d8daaec1dc9399eb0866ab2 /chrome
parent4685af7696690319a792030aafb329169cb93fa2 (diff)
downloadchromium_src-74a9f9f48c5832f548368eb8b43933f6b2a10e60.zip
chromium_src-74a9f9f48c5832f548368eb8b43933f6b2a10e60.tar.gz
chromium_src-74a9f9f48c5832f548368eb8b43933f6b2a10e60.tar.bz2
Checkin for CL: http://codereview.chromium.org/3061044/show
TEST=Backend: Various reports submitted from Chrome OS and Windows builds sent to the feedback test server. For Chromium OS, sent reports with current screenshot and saved screenshots; verified all reports for data accuracy and completion. Frontend: Tested the UI features by excersizing various options; tested not selecting any issue, tested switching between screenshot types. Review URL: http://codereview.chromium.org/3181027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56708 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd173
-rw-r--r--chrome/browser/browser.cc7
-rw-r--r--chrome/browser/browser_resources.grd4
-rw-r--r--chrome/browser/bug_report_util.cc169
-rw-r--r--chrome/browser/bug_report_util.h8
-rw-r--r--chrome/browser/cocoa/bug_report_window_controller.mm1
-rw-r--r--chrome/browser/dom_ui/bug_report_ui.cc632
-rw-r--r--chrome/browser/dom_ui/bug_report_ui.h20
-rw-r--r--chrome/browser/dom_ui/dom_ui_factory.cc3
-rw-r--r--chrome/browser/dom_ui/dom_ui_screenshot_source.cc112
-rw-r--r--chrome/browser/dom_ui/dom_ui_screenshot_source.h46
-rw-r--r--chrome/browser/resources/bug_report.css99
-rw-r--r--chrome/browser/resources/bug_report.html135
-rw-r--r--chrome/browser/resources/bug_report.js152
-rw-r--r--chrome/browser/resources/bug_report_cros.html169
-rw-r--r--chrome/browser/resources/bug_report_invalid.html10
-rw-r--r--chrome/browser/userfeedback/proto/chrome.proto55
-rw-r--r--chrome/browser/userfeedback/proto/common.proto8
-rw-r--r--chrome/browser/userfeedback/proto/extension.proto3
-rw-r--r--chrome/browser/userfeedback/proto/web.proto1
-rw-r--r--chrome/browser/views/browser_dialogs.h3
-rw-r--r--chrome/browser/views/bug_report_view.cc627
-rw-r--r--chrome/browser/views/bug_report_view.h173
-rw-r--r--chrome/browser/views/frame/browser_view.cc9
-rw-r--r--chrome/browser/wrench_menu_model.cc2
-rw-r--r--chrome/chrome_browser.gypi12
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/url_constants.cc3
-rw-r--r--chrome/common/url_constants.h3
30 files changed, 1734 insertions, 909 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a321950..3ea6fdb 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4224,27 +4224,59 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_BUGREPORT_TITLE" desc="Dialog title for bug report dialog">
Report Bug or Broken Web Site
</message>
- <message name="IDS_BUGREPORT_REPORT_PAGE_TITLE" desc="Label showing title of the page that will be reported">
+ <message name="IDS_BUGREPORT_REPORT_PAGE_TITLE" desc="Label showing the title of the page that will be reported">
Page title:
</message>
- <message name="IDS_BUGREPORT_REPORT_URL_LABEL" desc="Label showing URL that will be reported">
+ <message name="IDS_BUGREPORT_REPORT_URL_LABEL" desc="Label showing the URL that will be reported">
Page URL:
</message>
- <message name="IDS_BUGREPORT_USER_EMAIL_LABEL" desc="Label showing URL that will be reported">
+ <message name="IDS_BUGREPORT_USER_EMAIL_LABEL" desc="Label showing the e-mail address that will be reported">
User e-mail:
</message>
- <message name="IDS_BUGREPORT_DESCRIPTION_LABEL" desc="Label for description field">
+ <message name="IDS_BUGREPORT_DESCRIPTION_LABEL" desc="Label for the description field">
Description:
</message>
+ <message name="IDS_BUGREPORT_SCREENSHOT_LABEL" desc="Label for the screenshot field">
+ Screenshot:
+ </message>
+ <!-- For Mac compatibility -->
+ <message name="IDS_BUGREPORT_SOMETHING_MISSING" desc="In Title Case: Report a bug/problem type: Something's missing">
+ Something's Missing
+ </message>
+ <message name="IDS_BUGREPORT_BROWSER_CRASH" desc="Report a bug/problem type: Browser crashed">
+ Browser crash... go boom
+ </message>
+ <message name="IDS_BUGREPORT_OTHER_PROBLEM" desc="Report a bug/problem type: General feedback/other">
+ General feedback/other
+ </message>
+ <message name="IDS_BUGREPORT_PAGE_LOOKS_ODD" desc="Report a bug/problem type: Page looks odd">
+ Page looks odd
+ </message>
+ <message name="IDS_BUGREPORT_PAGE_WONT_LOAD" desc="Report a bug/problem type: Page won't load">
+ Page won't load
+ </message>
+ <message name="IDS_BUGREPORT_CANT_SIGN_IN" desc="Report a bug/problem type: Can't sign in">
+ Can't sign in
+ </message>
+ <!-- /Mac Compat -->
<if expr="pp_ifdef('chromeos')">
- <message name="IDS_BUGREPORT_INCLUDE_NEW_SCREEN_IMAGE" desc="Radio button for including a new screen image on the bug report dialog box">
- Send last active tab screen shot
+ <message name="IDS_BUGREPORT_NOTIFICATION_TITLE" desc="Title for the notification given to the user on completion (successful or failed) of user feedback">
+ Feedback submission status
+ </message>
+ <message name="IDS_BUGREPORT_FEEDBACK_STATUS_SUCCESS" desc="Message for the status of a feedback submission on success">
+ User Feedback submission succeeded
+ </message>
+ <message name="IDS_BUGREPORT_FEEDBACK_STATUS_FAIL" desc="Message for the status of a feedback submission failure">
+ User feedback submission failed: $1
</message>
<message name="IDS_BUGREPORT_INCLUDE_LAST_SCREEN_IMAGE" desc="Radio button for including the last screen image on the bug report dialog box">
Send last saved screen shot
</message>
- <message name="IDS_BUGREPORT_INCLUDE_NO_SCREEN_IMAGE" desc="Radio button for not including a screen image on the bug report dialog box">
- Do not send a screen shot
+ <message name="IDS_BUGREPORT_CURRENT_SCREENSHOTS" desc="Radio button for including the last screen image on the bug report dialog box">
+ Send a current page screen shot
+ </message>
+ <message name="IDS_BUGREPORT_SAVED_SCREENSHOTS" desc="Radio button for including the last screen image on the bug report dialog box">
+ Send a saved screen shot
</message>
<message name="IDS_BUGREPORT_INCLUDE_SYSTEM_INFORMATION_CHKBOX" desc="Checkbox for including system information on the bug report dialog box">
Send system information
@@ -4259,85 +4291,110 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_BUGREPORT_INCLUDE_PAGE_IMAGE_CHKBOX" desc="Checkbox for including page image">
Send screen shot of current page
</message>
+ <message name="IDS_BUGREPORT_INCLUDE_NEW_SCREEN_IMAGE" desc="Radio button for including a new screen image on the bug report dialog box">
+ Send last active tab screen shot
+ </message>
+ <message name="IDS_BUGREPORT_INCLUDE_NO_SCREENSHOT" desc="Radio button for not including a screen image on the bug report dialog box">
+ Do not send a screen shot
+ </message>
<message name="IDS_BUGREPORT_BUG_TYPE" desc="Label for bug type">
Bug type:
</message>
- <if expr="pp_ifdef('chromeos')">
- <message name="IDS_BUGREPORT_CONNECTIVITY_ISSUE" desc="Report a bug/problem type: Connectivity">
- Connectivity
+ <message name="IDS_BUGREPORT_PHISHING_PAGE" desc="Report a bug/problem type: Phishing page">
+ Phishing page
+ </message>
+ <message name="IDS_BUGREPORT_NO_ISSUE_SELECTED" desc="Message shown when no issue is selected before hitting submit">
+ Please select an issue type from the drop down before sending the report
+ </message>
+ <message name="IDS_BUGREPORT_ISSUE_WITH" desc="Label for issue with">
+ I see an issue with:
+ </message>
+ <if expr="not pp_ifdef('use_titlecase')">
+ <message name="IDS_BUGREPORT_SEND_REPORT" desc="Text for OK button on dialog">
+ Send report
</message>
- <message name="IDS_BUGREPORT_SYNC_ISSUE" desc="Report a bug/problem type: Sync">
- Sync
+ <message name="IDS_BUGREPORT_SEND_PHISHING_REPORT" desc="Text for report phishing button">
+ Open phishing report
</message>
- <message name="IDS_BUGREPORT_PAGE_FORMATTING" desc="Report a bug/problem type: Page formatting or layout">
- Page formatting
+ <message name="IDS_BUGREPORT_CHOOSE_ISSUE" desc="In Title Case: Report a bug/problem type: Choose issue with">
+ (choose an issue below)
</message>
- <message name="IDS_BUGREPORT_EXTENSION_ISSUE" desc="Report a bug/problem type: Extensions or apps">
- Extensions or apps
+ <message name="IDS_BUGREPORT_PAGE_FORMATTING" desc="In Title Case: Report a bug/problem type: Page formatting or layout">
+ Page formatting or layout
</message>
- <message name="IDS_BUGREPORT_SUSPEND_ISSUE" desc="Report a bug/problem type: Suspend or resume">
- Suspend or resume
+ <message name="IDS_BUGREPORT_PAGE_LOAD" desc="In Title Case: Report a bug/problem type: Pages not loading">
+ Pages not loading
</message>
- <message name="IDS_BUGREPORT_CRASH_ISSUE" desc="Report a bug/problem type: Crash">
- Crash
+ <message name="IDS_BUGREPORT_PLUGINS" desc="In Title Case: Report a bug/problem type: Plug-ins">
+ Plug-ins (e.g. Adobe Flash Player, Quicktime, etc)
</message>
- </if>
- <if expr="not pp_ifdef('use_titlecase')">
- <message name="IDS_BUGREPORT_SEND_REPORT" desc="Text for OK button on dialog">
- Send report
+ <message name="IDS_BUGREPORT_TABS" desc="In Title Case: Report a bug/problem type: Tabs or windows">
+ Tabs or windows
</message>
- <message name="IDS_BUGREPORT_SEND_PHISHING_REPORT" desc="Text for report phishing button">
- Open phishing report
+ <message name="IDS_BUGREPORT_NETWORK" desc="In Title Case: Report a bug/problem type: Network connection">
+ Network connection
</message>
- <message name="IDS_BUGREPORT_PAGE_WONT_LOAD" desc="Report a bug/problem type: Page won't load">
- Page won't load
+ <message name="IDS_BUGREPORT_CONNECTIVITY" desc="In Title Case: Report a bug/problem type: Connectivity issues">
+ Network connection
</message>
- <message name="IDS_BUGREPORT_PAGE_LOOKS_ODD" desc="Report a bug/problem type: Page looks odd">
- Page looks odd
+ <message name="IDS_BUGREPORT_STANDBY_RESUME" desc="In Title Case: Report a bug/problem type: Standby or Resume">
+ Network connection
</message>
- <message name="IDS_BUGREPORT_PHISHING_PAGE" desc="Report a bug/problem type: Phishing page">
- Phishing page
+ <message name="IDS_BUGREPORT_SYNC" desc="In Title Case: Report a bug/problem type: Synced preferences">
+ Synced preferences
</message>
- <message name="IDS_BUGREPORT_CANT_SIGN_IN" desc="Report a bug/problem type: Can't sign in">
- Can't sign in
+ <message name="IDS_BUGREPORT_CRASHES" desc="In Title Case: Report a bug/problem type: Crashes">
+ Crashes
</message>
- <message name="IDS_BUGREPORT_SOMETHING_MISSING" desc="Report a bug/problem type: Something's missing">
- Something's missing
+ <message name="IDS_BUGREPORT_EXTENSIONS" desc="In Title Case: Report a bug/problem type: Extensions or apps">
+ Extensions or apps
</message>
- <message name="IDS_BUGREPORT_BROWSER_CRASH" desc="Report a bug/problem type: Browser crashed">
- Browser crash... go boom
+ <message name="IDS_BUGREPORT_OTHER" desc="In Title Case: Report a bug/problem type: Other">
+ Other
</message>
- <message name="IDS_BUGREPORT_OTHER_PROBLEM" desc="Report a bug/problem type: General feedback/other">
+ <message name="IDS_BUGREPORT_GENERAL" desc="Report a bug/problem type: General feedback/other">
General feedback/other
</message>
+ <message name="IDS_BUGREPORT_PREVIEW_REPORT" desc="Text for the preview report button on dialog">
+ Preview report
+ </message>
</if>
<if expr="pp_ifdef('use_titlecase')">
- <message name="IDS_BUGREPORT_SEND_REPORT" desc="In Title Case: Text for OK button on dialog">
- Send Report
+ <message name="IDS_BUGREPORT_SEND_REPORT" desc="Text for the send report button on dialog">
+ Send report
</message>
- <message name="IDS_BUGREPORT_SEND_PHISHING_REPORT" desc="In Title Case: Text for report phishing button">
- Open Phishing Report
+ <message name="IDS_BUGREPORT_SEND_PHISHING_REPORT" desc="Text for report phishing button">
+ Open phishing report
</message>
- <message name="IDS_BUGREPORT_PAGE_WONT_LOAD" desc="In Title Case: Report a bug/problem type: Page won't load">
- Page Won't Load
+ <message name="IDS_BUGREPORT_CHOOSE_ISSUE" desc="In Title Case: Report a bug/problem type: Choose issue with">
+ (choose an issue below)
</message>
- <message name="IDS_BUGREPORT_PAGE_LOOKS_ODD" desc="In Title Case: Report a bug/problem type: Page looks odd">
- Page Looks Odd
+ <message name="IDS_BUGREPORT_PAGE_FORMATTING" desc="In Title Case: Report a bug/problem type: Page formatting or layout">
+ Page formatting or layout
</message>
- <message name="IDS_BUGREPORT_PHISHING_PAGE" desc="In Title Case: Report a bug/problem type: Phishing page">
- Phishing Page
+ <message name="IDS_BUGREPORT_PAGE_LOAD" desc="In Title Case: Report a bug/problem type: Pages not loading">
+ Pages not loading
</message>
- <message name="IDS_BUGREPORT_CANT_SIGN_IN" desc="In Title Case: Report a bug/problem type: Can't sign in">
- Can't Sign In
+ <message name="IDS_BUGREPORT_PLUGINS" desc="In Title Case: Report a bug/problem type: Plug-ins">
+ Plug-ins (e.g. Adobe Flash Player, Quicktime, etc)
</message>
- <message name="IDS_BUGREPORT_SOMETHING_MISSING" desc="In Title Case: Report a bug/problem type: Something's missing">
- Something's Missing
+ <message name="IDS_BUGREPORT_TABS" desc="In Title Case: Report a bug/problem type: Tabs or windows">
+ Tabs or windows
</message>
- <message name="IDS_BUGREPORT_BROWSER_CRASH" desc="In Title Case: Report a bug/problem type: Browser crashed">
- Browser Crash... Go Boom
+ <message name="IDS_BUGREPORT_NETWORK" desc="In Title Case: Report a bug/problem type: Network connection">
+ Network connection
</message>
- <message name="IDS_BUGREPORT_OTHER_PROBLEM" desc="In Title Case: Report a bug/problem type: General feedback/other">
- General feedback/other
+ <message name="IDS_BUGREPORT_SYNC" desc="In Title Case: Report a bug/problem type: Synced preferences">
+ Synced preferences
+ </message>
+ <message name="IDS_BUGREPORT_CRASHES" desc="In Title Case: Report a bug/problem type: Crashes">
+ Crashes
+ </message>
+ <message name="IDS_BUGREPORT_EXTENSIONS" desc="In Title Case: Report a bug/problem type: Extensions or apps">
+ Extensions or apps
+ </message>
+ <message name="IDS_BUGREPORT_OTHER" desc="In Title Case: Report a bug/problem type: Other">
+ Other
</message>
</if>
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index ac91d86..6cad802 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1728,15 +1728,8 @@ void Browser::OpenTaskManager() {
}
void Browser::OpenBugReportDialog() {
-#if defined(OS_CHROMEOS)
UserMetrics::RecordAction(UserMetricsAction("ReportBug"), profile_);
window_->ShowReportBugDialog();
-#else
- TabContents* contents = GetSelectedTabContents();
- if (!contents)
- return;
- ShowBrokenPageTab(contents);
-#endif
}
void Browser::ToggleBookmarkBar() {
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 3c277f7..22e76d1 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -60,9 +60,11 @@ without changes to the corresponding grd file. eadee -->
<include name="IDR_REMOTING_SETUP_FLOW_HTML" file="remoting\resources\setup_flow.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_REMOTING_SETUP_DONE_HTML" file="remoting\resources\setup_done.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_TRANSLATE_JS" file="resources\translate.js" type="BINDATA" />
-
+ <include name="IDR_BUGREPORT_HTML" file="resources\bug_report.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_BUGREPORT_HTML_INVALID" file="resources\bug_report_invalid.html" flattenhtml="true" type="BINDATA" />
<if expr="pp_ifdef('chromeos')">
<include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_BUGREPORT_HTML_CHROMEOS" file="resources\bug_report_cros.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_FILEBROWSE_HTML" file="resources\filebrowse.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_HOST_REGISTRATION_PAGE_HTML" file="resources\host_registration_page.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_MEDIAPLAYER_HTML" file="resources\mediaplayer.html" flattenhtml="true" type="BINDATA" />
diff --git a/chrome/browser/bug_report_util.cc b/chrome/browser/bug_report_util.cc
index d60ef4e..85f7ac1 100644
--- a/chrome/browser/bug_report_util.cc
+++ b/chrome/browser/bug_report_util.cc
@@ -4,22 +4,34 @@
#include "chrome/browser/bug_report_util.h"
+#include <sstream>
#include <string>
+#include "app/l10n_util.h"
+#include "base/command_line.h"
#include "base/file_version_info.h"
+#include "base/file_util.h"
+#include "base/singleton.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process_impl.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/safe_browsing/safe_browsing_util.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/url_fetcher.h"
#include "googleurl/src/gurl.h"
#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
#include "net/url_request/url_request_status.h"
#include "unicode/locid.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/notifications/system_notification.h"
+#endif
+
namespace {
const int kBugReportVersion = 1;
@@ -28,27 +40,60 @@ const char kReportPhishingUrl[] =
"http://www.google.com/safebrowsing/report_phish/";
// URL to post bug reports to.
-const char* const kBugReportPostUrl =
+static char const kBugReportPostUrl[] =
"https://www.google.com/tools/feedback/chrome/__submit";
-const char* const kProtBufMimeType = "application/x-protobuf";
-const char* const kPngMimeType = "image/png";
+static char const kProtBufMimeType[] = "application/x-protobuf";
+static char const kPngMimeType[] = "image/png";
// Tags we use in product specific data
-const char* const kPageTitleTag = "PAGE TITLE";
-const char* const kProblemTypeIdTag = "PROBLEM TYPE ID";
-const char* const kProblemTypeTag = "PROBLEM TYPE";
-const char* const kChromeVersionTag = "CHROME VERSION";
-const char* const kOsVersionTag = "OS VERSION";
+static char const kPageTitleTag[] = "PAGE TITLE";
+static char const kProblemTypeIdTag[] = "PROBLEM TYPE ID";
+static char const kProblemTypeTag[] = "PROBLEM TYPE";
+static char const kChromeVersionTag[] = "CHROME VERSION";
+static char const kOsVersionTag[] = "OS VERSION";
+
+static char const kNotificationId[] = "feedback.chromeos";
+
+static int const kHttpPostSuccessNoContent = 204;
+static int const kHttpPostFailNoConnection = -1;
+static int const kHttpPostFailClientError = 400;
+static int const kHttpPostFailServerError = 500;
+
+} // namespace
+
+#if defined(OS_CHROMEOS)
+class FeedbackNotification {
+ public:
+ // Previous notification cleanup is handled by scoped_ptr.
+ // Note: notification will show only on one profile at a time.
+ void Show(Profile* profile, const string16& message, bool urgent) {
+ notification_.reset(
+ new chromeos::SystemNotification(profile, kNotificationId,
+ IDR_STATUSBAR_FEEDBACK,
+ l10n_util::GetStringUTF16(
+ IDS_BUGREPORT_NOTIFICATION_TITLE)));
+ notification_->Show(message, urgent);
+ }
-} // namespace
+ private:
+ FeedbackNotification() {}
+ friend struct DefaultSingletonTraits<FeedbackNotification>;
+
+ scoped_ptr<chromeos::SystemNotification> notification_;
+ DISALLOW_COPY_AND_ASSIGN(FeedbackNotification);
+};
+#endif
// Simple URLFetcher::Delegate to clean up URLFetcher on completion.
class BugReportUtil::PostCleanup : public URLFetcher::Delegate {
public:
+#if defined(OS_CHROMEOS)
+ explicit PostCleanup(Profile* profile);
+#else
PostCleanup();
-
+#endif
// Overridden from URLFetcher::Delegate.
virtual void OnURLFetchComplete(const URLFetcher* source,
const GURL& url,
@@ -61,10 +106,17 @@ class BugReportUtil::PostCleanup : public URLFetcher::Delegate {
virtual ~PostCleanup() {}
private:
+ Profile* profile_;
+
DISALLOW_COPY_AND_ASSIGN(PostCleanup);
};
-BugReportUtil::PostCleanup::PostCleanup() {
+#if defined(OS_CHROMEOS)
+ BugReportUtil::PostCleanup::PostCleanup(Profile* profile)
+ : profile_(profile) {
+#else
+ BugReportUtil::PostCleanup::PostCleanup() {
+#endif
}
void BugReportUtil::PostCleanup::OnURLFetchComplete(
@@ -74,10 +126,38 @@ void BugReportUtil::PostCleanup::OnURLFetchComplete(
int response_code,
const ResponseCookies& cookies,
const std::string& data) {
- // if not 204, something went wrong
- if (response_code != 204)
- LOG(WARNING) << "Submission to feedback server failed. Response code: " <<
- response_code << std::endl;
+
+ std::stringstream error_stream;
+ if (response_code == kHttpPostSuccessNoContent) {
+ error_stream << "Success";
+ } else if (response_code == kHttpPostFailNoConnection) {
+ error_stream << "No connection to server.";
+ } else if ((response_code > kHttpPostFailClientError) &&
+ (response_code < kHttpPostFailServerError)) {
+ error_stream << "Client error: HTTP response code " << response_code;
+ } else if (response_code > kHttpPostFailServerError) {
+ error_stream << "Server error: HTTP response code " << response_code;
+ } else {
+ error_stream << "Unknown error: HTTP response code " << response_code;
+ }
+
+ LOG(WARNING) << "Submission to feedback server (" << url <<
+ ") status: " << error_stream.str() << std::endl;
+
+#if defined(OS_CHROMEOS)
+ // Show the notification to the user; this notification will stay active till
+ // either the user closes it, or we display another notification.
+ if (response_code == kHttpPostSuccessNoContent) {
+ Singleton<FeedbackNotification>()->Show(profile_, l10n_util::GetStringUTF16(
+ IDS_BUGREPORT_FEEDBACK_STATUS_SUCCESS), false);
+ } else {
+ Singleton<FeedbackNotification>()->Show(profile_,
+ l10n_util::GetStringFUTF16(IDS_BUGREPORT_FEEDBACK_STATUS_FAIL,
+ ASCIIToUTF16(error_stream.str())),
+ true);
+ }
+#endif
+
// Delete the URLFetcher.
delete source;
// And then delete ourselves.
@@ -112,9 +192,20 @@ void BugReportUtil::SetOSVersion(std::string *os_version) {
}
// static
+std::string BugReportUtil::feedback_server_("");
+
+// static
+void BugReportUtil::SetFeedbackServer(const std::string& server) {
+ feedback_server_ = server;
+}
+
+
+// static
void BugReportUtil::AddFeedbackData(
userfeedback::ExternalExtensionSubmit* feedback_data,
const std::string& key, const std::string& value) {
+ // We have no reason to log any empty values - gives us no data
+ if (value == "") return;
// Create log_value object and add it to the web_data object
userfeedback::ProductSpecificData log_value;
log_value.set_key(key);
@@ -128,19 +219,25 @@ void BugReportUtil::SendReport(Profile* profile,
const std::string& page_title_text,
int problem_type,
const std::string& page_url_text,
- const std::string& user_email_text,
const std::string& description,
const char* png_data,
int png_data_length,
int png_width,
#if defined(OS_CHROMEOS)
int png_height,
- const std::string& problem_type_text,
+ const std::string& user_email_text,
const chromeos::LogDictionaryType* const sys_info) {
#else
int png_height) {
#endif
- GURL post_url(kBugReportPostUrl);
+ GURL post_url;
+
+ if (CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kFeedbackServer))
+ post_url = GURL(CommandLine::ForCurrentProcess()->
+ GetSwitchValueASCII(switches::kFeedbackServer));
+ else
+ post_url = GURL(kBugReportPostUrl);
// Create google feedback protocol buffer objects
userfeedback::ExternalExtensionSubmit feedback_data;
@@ -160,23 +257,17 @@ void BugReportUtil::SendReport(Profile* profile,
AddFeedbackData(&feedback_data, std::string(kPageTitleTag),
page_title_text);
- AddFeedbackData(&feedback_data, std::string(kProblemTypeIdTag),
- StringPrintf("%d\r\n", problem_type));
-
#if defined(OS_CHROMEOS)
- AddFeedbackData(&feedback_data, std::string(kProblemTypeTag),
- problem_type_text);
-#endif
-
// Add the user e-mail to the feedback object
common_data->set_user_email(user_email_text);
+#endif
// Add the description to the feedback object
common_data->set_description(description);
// Add the language
std::string chrome_locale = g_browser_process->GetApplicationLocale();
- common_data->set_source_descripton_language(chrome_locale);
+ common_data->set_source_description_language(chrome_locale);
// Set the url
web_data->set_url(page_url_text);
@@ -222,9 +313,33 @@ void BugReportUtil::SendReport(Profile* profile,
*(feedback_data.mutable_screenshot()) = screenshot;
}
+ // Set our Chrome specific data
+ userfeedback::ChromeData chrome_data;
+#if defined(OS_CHROMEOS)
+ chrome_data.set_chrome_platform(
+ userfeedback::ChromeData_ChromePlatform_CHROME_OS);
+ userfeedback::ChromeOsData chrome_os_data;
+ chrome_os_data.set_category(
+ (userfeedback::ChromeOsData_ChromeOsCategory) problem_type);
+ *(chrome_data.mutable_chrome_os_data()) = chrome_os_data;
+#else
+ chrome_data.set_chrome_platform(
+ userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER);
+ userfeedback::ChromeBrowserData chrome_browser_data;
+ chrome_browser_data.set_category(
+ (userfeedback::ChromeBrowserData_ChromeBrowserCategory) problem_type);
+ *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data;
+#endif
+
+ *(feedback_data.mutable_chrome_data()) = chrome_data;
+
// We have the body of our POST, so send it off to the server.
URLFetcher* fetcher = new URLFetcher(post_url, URLFetcher::POST,
- new BugReportUtil::PostCleanup);
+#if defined(OS_CHROMEOS)
+ new BugReportUtil::PostCleanup(profile));
+#else
+ new BugReportUtil::PostCleanup());
+#endif
fetcher->set_request_context(profile->GetRequestContext());
std::string post_body;
diff --git a/chrome/browser/bug_report_util.h b/chrome/browser/bug_report_util.h
index d4ffd77..7b51a74 100644
--- a/chrome/browser/bug_report_util.h
+++ b/chrome/browser/bug_report_util.h
@@ -64,19 +64,21 @@ class BugReportUtil {
// all the call sites or making it a wrapper around another util.
static void SetOSVersion(std::string *os_version);
+ // This sets the address of the feedback server to be used by SendReport
+ static void SetFeedbackServer(const std::string& server);
+
// Generates bug report data.
static void SendReport(Profile* profile,
const std::string& page_title_text,
int problem_type,
const std::string& page_url_text,
- const std::string& user_email_text,
const std::string& description,
const char* png_data,
int png_data_length,
int png_width,
#if defined(OS_CHROMEOS)
int png_height,
- const std::string& problem_type_text,
+ const std::string& user_email_text,
const chromeos::LogDictionaryType* const sys_info);
#else
int png_height);
@@ -94,6 +96,8 @@ class BugReportUtil {
userfeedback::ExternalExtensionSubmit* feedback_data,
const std::string& key, const std::string& value);
+ static std::string feedback_server_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(BugReportUtil);
};
diff --git a/chrome/browser/cocoa/bug_report_window_controller.mm b/chrome/browser/cocoa/bug_report_window_controller.mm
index c7e920da..df29f99 100644
--- a/chrome/browser/cocoa/bug_report_window_controller.mm
+++ b/chrome/browser/cocoa/bug_report_window_controller.mm
@@ -113,7 +113,6 @@
base::SysNSStringToUTF8(pageTitle_),
[self bugTypeFromIndex],
base::SysNSStringToUTF8(pageURL_),
- std::string(),
base::SysNSStringToUTF8(bugDescription_),
sendScreenshot_ && !pngData_.empty() ?
reinterpret_cast<const char *>(&(pngData_[0])) : NULL,
diff --git a/chrome/browser/dom_ui/bug_report_ui.cc b/chrome/browser/dom_ui/bug_report_ui.cc
new file mode 100644
index 0000000..45f06e2
--- /dev/null
+++ b/chrome/browser/dom_ui/bug_report_ui.cc
@@ -0,0 +1,632 @@
+// Copyright (c) 2009 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/dom_ui/bug_report_ui.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/path_service.h"
+#include "base/singleton.h"
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "base/string_number_conversions.h"
+#include "base/thread.h"
+#include "base/time.h"
+#include "base/values.h"
+#include "base/weak_ptr.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/bug_report_util.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/dom_ui/dom_ui_screenshot_source.h"
+#include "chrome/browser/download/download_manager.h"
+#include "chrome/browser/download/download_util.h"
+#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/thumbnail_generator.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/common/time_format.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/common/net/url_fetcher.h"
+#include "gfx/codec/png_codec.h"
+#include "net/base/escape.h"
+#include "views/window/window.h"
+
+#include "grit/browser_resources.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+
+#if defined(OS_LINUX)
+#include "app/x11_util.h"
+#elif defined(OS_MACOSX)
+#include "base/mac_util.h"
+#else
+#include "app/win_util.h"
+#endif
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/syslogs_library.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#endif
+
+static const char kScreenshotBaseUrl[] = "chrome://screenshots/";
+static const char kCurrentScreenshotUrl[] = "chrome://screenshots/current";
+#if defined(OS_CHROMEOS)
+static const char kSavedScreenshotsUrl[] = "chrome://screenshots/saved/";
+
+static const char kScreenshotPattern[] = "*.png";
+static const char kScreenshotsRelativePath[] = "/Screenshots";
+#endif
+
+namespace {
+#if defined(OS_CHROMEOS)
+
+void GetSavedScreenshots(std::vector<std::string>* saved_screenshots,
+ base::WaitableEvent* done) {
+ saved_screenshots->clear();
+
+ FilePath fileshelf_path;
+ if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
+ &fileshelf_path)) {
+ done->Signal();
+ return;
+ }
+
+ // TODO(rkc): Change this to use FilePath.Append() once the cros
+ // issue with it is fixed
+ FilePath screenshots_path(fileshelf_path.value() +
+ std::string(kScreenshotsRelativePath));
+ file_util::FileEnumerator screenshots(screenshots_path, false,
+ file_util::FileEnumerator::FILES,
+ std::string(kScreenshotPattern));
+ FilePath screenshot = screenshots.Next();
+ while (!screenshot.empty()) {
+ saved_screenshots->push_back(std::string(kSavedScreenshotsUrl) +
+ screenshot.BaseName().value());
+ screenshot = screenshots.Next();
+ }
+ done->Signal();
+}
+
+// This fuction posts a task to the file thread to create/list all the current
+// and saved screenshots.
+void GetScreenshotUrls(std::vector<std::string>* saved_screenshots) {
+ base::WaitableEvent done(true, false);
+ ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
+ NewRunnableFunction(&GetSavedScreenshots,
+ saved_screenshots, &done));
+ done.Wait();
+}
+
+std::string GetUserEmail() {
+ chromeos::UserManager* manager = chromeos::UserManager::Get();
+ if (!manager)
+ return std::string();
+ else
+ return manager->logged_in_user().email();
+}
+
+chromeos::LogDictionaryType* GetSystemInformation() {
+ chromeos::LogDictionaryType* sys_info = NULL;
+ chromeos::SyslogsLibrary* syslogs_lib =
+ chromeos::CrosLibrary::Get()->GetSyslogsLibrary();
+
+ if (syslogs_lib)
+ sys_info = syslogs_lib->GetSyslogs(NULL);
+
+ return sys_info;
+}
+#endif
+
+
+} // namespace
+
+
+namespace browser {
+
+// TODO(rkc): Eventually find a better way to do this
+std::vector<unsigned char>* last_screenshot_png = 0;
+gfx::Rect screen_size;
+
+void RefreshLastScreenshot(views::Window* parent) {
+ // Grab an exact snapshot of the window that the user is seeing (i.e. as
+ // rendered--do not re-render, and include windowed plugins).
+ if (last_screenshot_png)
+ last_screenshot_png->clear();
+ else
+ last_screenshot_png = new std::vector<unsigned char>;
+
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+ screen_size = parent->GetBounds();
+ x11_util::GrabWindowSnapshot(parent->GetNativeWindow(), last_screenshot_png);
+#elif defined(OS_MACOSX)
+ int width = 0, height = 0;
+ mac_util::GrabWindowSnapshot(parent->GetNativeWindow(), last_screenshot_png,
+ &width, &height);
+#else
+ screen_size = parent->GetBounds();
+ win_util::GrabWindowSnapshot(parent->GetNativeWindow(), last_screenshot_png);
+#endif
+}
+
+// Global "display this dialog" function declared in browser_dialogs.h.
+void ShowHtmlBugReportView(views::Window* parent, Browser* browser) {
+ std::string bug_report_url = std::string(chrome::kChromeUIBugReportURL) +
+ base::IntToString(browser->selected_index());
+
+ RefreshLastScreenshot(parent);
+ browser->ShowSingletonTab(GURL(bug_report_url));
+}
+
+} // namespace browser
+
+
+class BugReportUIHTMLSource : public ChromeURLDataManager::DataSource {
+ public:
+ explicit BugReportUIHTMLSource(base::StringPiece html);
+
+ // Called when the network layer has requested a resource underneath
+ // the path we registered.
+ virtual void StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id);
+ virtual std::string GetMimeType(const std::string&) const {
+ return "text/html";
+ }
+
+ private:
+ base::StringPiece bug_report_html_;
+ ~BugReportUIHTMLSource() {}
+
+ DISALLOW_COPY_AND_ASSIGN(BugReportUIHTMLSource);
+};
+
+class TaskProxy;
+
+// The handler for Javascript messages related to the "bug report" dialog
+class BugReportHandler : public DOMMessageHandler,
+ public base::SupportsWeakPtr<BugReportHandler> {
+ public:
+ explicit BugReportHandler(TabContents* tab);
+ virtual ~BugReportHandler();
+
+ // Init work after Attach.
+ base::StringPiece Init();
+
+ // DOMMessageHandler implementation.
+ virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
+ virtual void RegisterMessages();
+ void OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data);
+
+ void HandleGetDialogDefaults(const Value* value);
+ void HandleRefreshScreenshots(const Value* value);
+ void HandleSendReport(const Value* value);
+ void HandleCancel(const Value* value);
+
+ void SetupScreenshotsSource();
+ void ClobberScreenshotsSource();
+
+ private:
+ Browser* browser_;
+ std::string page_url_;
+ Profile* profile_;
+ TabContents* tab_;
+ TabContents* target_tab_;
+ DOMUIScreenshotSource* screenshot_source_;
+#if defined (OS_CHROMEOS)
+ chromeos::LogDictionaryType* sys_info_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(BugReportHandler);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// BugReportHTMLSource
+//
+////////////////////////////////////////////////////////////////////////////////
+
+BugReportUIHTMLSource::BugReportUIHTMLSource(base::StringPiece html)
+ : DataSource(chrome::kChromeUIBugReportHost, MessageLoop::current()) {
+ bug_report_html_ = html;
+}
+
+void BugReportUIHTMLSource::StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id) {
+ DictionaryValue localized_strings;
+ localized_strings.SetString(std::string("title"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_TITLE));
+ localized_strings.SetString(std::string("issue-with"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_ISSUE_WITH));
+ localized_strings.SetString(std::string("page-url"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_REPORT_URL_LABEL));
+ localized_strings.SetString(std::string("description"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_DESCRIPTION_LABEL));
+ localized_strings.SetString(std::string("screenshot"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_SCREENSHOT_LABEL));
+#if defined(OS_CHROMEOS)
+ localized_strings.SetString(std::string("user-email"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_USER_EMAIL_LABEL));
+ localized_strings.SetString(std::string("currentscreenshots"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_CURRENT_SCREENSHOTS));
+ localized_strings.SetString(std::string("savedscreenshots"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_SAVED_SCREENSHOTS));
+ localized_strings.SetString(std::string("sysinfo"),
+ l10n_util::GetStringUTF8(
+ IDS_BUGREPORT_INCLUDE_SYSTEM_INFORMATION_CHKBOX));
+#else
+ localized_strings.SetString(std::string("currentscreenshots"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_INCLUDE_NEW_SCREEN_IMAGE));
+#endif
+ localized_strings.SetString(std::string("noscreenshot"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_INCLUDE_NO_SCREENSHOT));
+
+ localized_strings.SetString(std::string("send-report"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_SEND_REPORT));
+ localized_strings.SetString(std::string("cancel"),
+ l10n_util::GetStringUTF8(IDS_CANCEL));
+
+ // Option strings for the "issue with" drop-down.
+ localized_strings.SetString(std::string("issue-choose"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_CHOOSE_ISSUE));
+
+ localized_strings.SetString(std::string("no-issue-selected"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_NO_ISSUE_SELECTED));
+
+
+ // TODO(rkc): Find some way to ensure this order of dropdowns is in sync
+ // with the order in the userfeedback ChromeData proto buffer
+#if defined(OS_CHROMEOS)
+ // Dropdown for ChromeOS:
+ //
+ // Connectivity
+ // Sync
+ // Crash
+ // Page Formatting
+ // Extensions or Apps
+ // Standby or Resume
+ // Phishing Page
+ // General Feedback/Other
+
+ localized_strings.SetString(std::string("issue-connectivity"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_CONNECTIVITY));
+ localized_strings.SetString(std::string("issue-sync"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_SYNC));
+ localized_strings.SetString(std::string("issue-crashes"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_CRASHES));
+ localized_strings.SetString(std::string("issue-page-formatting"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_PAGE_FORMATTING));
+ localized_strings.SetString(std::string("issue-extensions"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_EXTENSIONS));
+ localized_strings.SetString(std::string("issue-standby"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_STANDBY_RESUME));
+ localized_strings.SetString(std::string("issue-phishing"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_PHISHING_PAGE));
+ localized_strings.SetString(std::string("issue-other"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_GENERAL));
+#else
+ // Dropdown for Chrome:
+ //
+ // Page formatting or layout
+ // Pages not loading
+ // Plug-ins (e.g. Adobe Flash Player, Quicktime, etc)
+ // Tabs or windows
+ // Synced preferences
+ // Crashes
+ // Extensions or apps
+ // Phishing
+ // Other
+
+ localized_strings.SetString(std::string("issue-page-formatting"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_PAGE_FORMATTING));
+ localized_strings.SetString(std::string("issue-page-load"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_PAGE_LOAD));
+ localized_strings.SetString(std::string("issue-plugins"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_PLUGINS));
+ localized_strings.SetString(std::string("issue-tabs"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_TABS));
+ localized_strings.SetString(std::string("issue-sync"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_SYNC));
+ localized_strings.SetString(std::string("issue-crashes"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_CRASHES));
+ localized_strings.SetString(std::string("issue-extensions"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_EXTENSIONS));
+ localized_strings.SetString(std::string("issue-phishing"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_PHISHING_PAGE));
+ localized_strings.SetString(std::string("issue-other"),
+ l10n_util::GetStringUTF8(IDS_BUGREPORT_OTHER));
+#endif
+
+ SetFontAndTextDirection(&localized_strings);
+
+ const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
+ bug_report_html_, &localized_strings);
+
+ scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
+ html_bytes->data.resize(full_html.size());
+ std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
+
+ SendResponse(request_id, html_bytes);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// BugErportHandler
+//
+////////////////////////////////////////////////////////////////////////////////
+BugReportHandler::BugReportHandler(TabContents* tab)
+ : profile_(NULL), tab_(tab), screenshot_source_(NULL) {
+ browser_ = BrowserList::GetLastActive();
+}
+
+BugReportHandler::~BugReportHandler() {
+}
+
+void BugReportHandler::ClobberScreenshotsSource() {
+ // Re-create our screenshots data source (this clobbers the last source)
+ // setting the screenshot to NULL, effectively disabling the source
+ // TODO(rkc): Once there is a method to 'remove' a source, change this code
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ Singleton<ChromeURLDataManager>::get(),
+ &ChromeURLDataManager::AddDataSource,
+ make_scoped_refptr(new DOMUIScreenshotSource(NULL))));
+
+ // clobber last screenshot
+ if (browser::last_screenshot_png)
+ browser::last_screenshot_png->clear();
+}
+
+void BugReportHandler::SetupScreenshotsSource() {
+ // If we don't already have a screenshot source object created, create one.
+ if (!screenshot_source_)
+ screenshot_source_ = new DOMUIScreenshotSource(
+ browser::last_screenshot_png);
+
+ // Add the source to the data manager.
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ Singleton<ChromeURLDataManager>::get(),
+ &ChromeURLDataManager::AddDataSource,
+ make_scoped_refptr(screenshot_source_)));
+}
+
+DOMMessageHandler* BugReportHandler::Attach(DOMUI* dom_ui) {
+ SetupScreenshotsSource();
+ return DOMMessageHandler::Attach(dom_ui);
+}
+
+base::StringPiece BugReportHandler::Init() {
+ std::string page_url;
+ if (tab_->controller().GetActiveEntry()) {
+ page_url = tab_->controller().GetActiveEntry()->url().spec();
+ }
+
+ std::string params = page_url.substr(strlen(chrome::kChromeUIBugReportURL));
+
+ int index = 0;
+ if (!base::StringToInt(params, &index)) {
+ ClobberScreenshotsSource();
+ return base::StringPiece(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_BUGREPORT_HTML_INVALID));
+ }
+
+ // Sanity checks.
+ if (((index == 0) && (params != "0")) || (index >= browser_->tab_count())) {
+ ClobberScreenshotsSource();
+ return base::StringPiece(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_BUGREPORT_HTML_INVALID));
+ }
+
+ if (browser_)
+ target_tab_ = browser_->GetTabContentsAt(index);
+ else
+ LOG(FATAL) << "Failed to get last active browser.";
+
+ return base::StringPiece(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+#if defined(OS_CHROMEOS)
+ IDR_BUGREPORT_HTML_CHROMEOS));
+#else
+ IDR_BUGREPORT_HTML));
+#endif
+}
+
+void BugReportHandler::RegisterMessages() {
+ dom_ui_->RegisterMessageCallback("getDialogDefaults",
+ NewCallback(this, &BugReportHandler::HandleGetDialogDefaults));
+ dom_ui_->RegisterMessageCallback("refreshScreenshots",
+ NewCallback(this, &BugReportHandler::HandleRefreshScreenshots));
+ dom_ui_->RegisterMessageCallback("sendReport",
+ NewCallback(this, &BugReportHandler::HandleSendReport));
+ dom_ui_->RegisterMessageCallback("cancel",
+ NewCallback(this, &BugReportHandler::HandleCancel));
+}
+
+void BugReportHandler::HandleGetDialogDefaults(const Value* value) {
+ // send back values which the dialog js needs initially
+ ListValue dialog_defaults;
+
+ // 0: current url
+ if (target_tab_)
+ dialog_defaults.Append(new StringValue(
+ target_tab_->controller().GetActiveEntry()->url().spec()));
+ else
+ dialog_defaults.Append(new StringValue(""));
+
+#if defined(OS_CHROMEOS)
+ // 1: user e-mail
+ sys_info_ = GetSystemInformation();
+ dialog_defaults.Append(new StringValue(chrome::kAboutSystemURL));
+
+ // 2: user e-mail
+ dialog_defaults.Append(new StringValue(GetUserEmail()));
+#endif
+
+ dom_ui_->CallJavascriptFunction(L"setupDialogDefaults", dialog_defaults);
+}
+
+void BugReportHandler::HandleRefreshScreenshots(const Value* value) {
+ ListValue screenshots;
+ screenshots.Append(new StringValue(std::string(kCurrentScreenshotUrl)));
+
+
+#if defined(OS_CHROMEOS)
+ std::vector<std::string> saved_screenshots;
+ GetScreenshotUrls(&saved_screenshots);
+
+ ListValue* saved_screenshot_list = new ListValue();
+ for (size_t i = 0; i < saved_screenshots.size(); ++i)
+ saved_screenshot_list->Append(new StringValue(saved_screenshots[i]));
+ screenshots.Append(saved_screenshot_list);
+#endif
+ dom_ui_->CallJavascriptFunction(L"setupScreenshots", screenshots);
+}
+
+void BugReportHandler::HandleSendReport(const Value* value) {
+ if (value && value->GetType() == Value::TYPE_LIST) {
+ const ListValue* list_value = static_cast<const ListValue*>(value);
+
+ ListValue::const_iterator i = list_value->begin();
+ if (i == list_value->end()) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+
+ // #0 - Problem type.
+ std::string problem_type_str;
+ int problem_type = 0;
+ (*i)->GetAsString(&problem_type_str);
+ if (!base::StringToInt(problem_type_str, &problem_type)) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+ if (++i == list_value->end()) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+
+ // #1 - Page url.
+ std::string page_url;
+ (*i)->GetAsString(&page_url);
+ if (++i == list_value->end()) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+
+ // #2 - Description.
+ std::string description;
+ (*i)->GetAsString(&description);
+ if (++i == list_value->end()) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+
+ // #3 - Screenshot to send.
+ std::string screenshot_path;
+ (*i)->GetAsString(&screenshot_path);
+ screenshot_path.erase(0, strlen(kScreenshotBaseUrl));
+#if defined(OS_CHROMEOS)
+ if (++i == list_value->end()) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+
+ // #4 - User e-mail
+ std::string user_email;
+ (*i)->GetAsString(&user_email);
+ if (++i == list_value->end()) {
+ LOG(ERROR) << "Incorrect data passed to sendReport.";
+ return;
+ }
+
+ // #5 - System info checkbox.
+ std::string sys_info_checkbox;
+ (*i)->GetAsString(&sys_info_checkbox);
+#endif
+
+ // Get the image to send in the report.
+ char* image_data = NULL;
+ int image_data_size = 0;
+ // Make sure this object remains in scope till SendReport returns.
+ std::vector<unsigned char> image;
+ if (screenshot_path.size() > 0) {
+ image = screenshot_source_->GetScreenshot(screenshot_path);
+ image_data = reinterpret_cast<char*>(&(image.front()));
+ image_data_size = image.size();
+ }
+
+ BugReportUtil::SendReport(browser_->profile(),
+ UTF16ToUTF8(target_tab_->GetTitle()),
+ problem_type,
+ page_url,
+ description,
+ image_data,
+ image_data_size, browser::screen_size.width(),
+#if defined(OS_CHROMEOS)
+ browser::screen_size.height(),
+ user_email,
+ ((sys_info_checkbox == "true") ?
+ GetSystemInformation() : NULL));
+#else
+ browser::screen_size.height());
+#endif
+
+ } else {
+ LOG(ERROR) << "Incorrect data passed from bug report dialog.";
+ }
+ browser_->CloseTabContents(tab_);
+ ClobberScreenshotsSource();
+}
+
+void BugReportHandler::HandleCancel(const Value* value) {
+ browser_->CloseTabContents(tab_);
+ ClobberScreenshotsSource();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// BugReportUI
+//
+////////////////////////////////////////////////////////////////////////////////
+BugReportUI::BugReportUI(TabContents* tab) : HtmlDialogUI(tab) {
+ BugReportHandler* handler = new BugReportHandler(tab);
+ AddMessageHandler((handler)->Attach(this));
+
+ // The handler's init will specify which html
+ // resource we'll display to the user
+ BugReportUIHTMLSource* html_source =
+ new BugReportUIHTMLSource(handler->Init());
+ // Set up the chrome://bugreport/ source.
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ Singleton<ChromeURLDataManager>::get(),
+ &ChromeURLDataManager::AddDataSource,
+ make_scoped_refptr(html_source)));
+}
diff --git a/chrome/browser/dom_ui/bug_report_ui.h b/chrome/browser/dom_ui/bug_report_ui.h
new file mode 100644
index 0000000..907dbb2
--- /dev/null
+++ b/chrome/browser/dom_ui/bug_report_ui.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2009 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_DOM_UI_BUG_REPORT_UI_H_
+#define CHROME_BROWSER_DOM_UI_BUG_REPORT_UI_H_
+
+#include "chrome/browser/dom_ui/html_dialog_ui.h"
+
+class TabContents;
+
+class BugReportUI : public HtmlDialogUI {
+ public:
+ explicit BugReportUI(TabContents* contents);
+ private:
+
+ DISALLOW_COPY_AND_ASSIGN(BugReportUI);
+};
+
+#endif // CHROME_BROWSER_DOM_UI_BUG_REPORT_UI_H_
diff --git a/chrome/browser/dom_ui/dom_ui_factory.cc b/chrome/browser/dom_ui/dom_ui_factory.cc
index 5c50067..3288d08 100644
--- a/chrome/browser/dom_ui/dom_ui_factory.cc
+++ b/chrome/browser/dom_ui/dom_ui_factory.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/dom_ui/bookmarks_ui.h"
+#include "chrome/browser/dom_ui/bug_report_ui.h"
#include "chrome/browser/dom_ui/downloads_ui.h"
#include "chrome/browser/dom_ui/devtools_ui.h"
#include "chrome/browser/dom_ui/history_ui.h"
@@ -102,6 +103,8 @@ static DOMUIFactoryFunction GetDOMUIFactoryFunction(const GURL& url) {
// after the host name.
if (url.host() == chrome::kChromeUIBookmarksHost)
return &NewDOMUI<BookmarksUI>;
+ if (url.host() == chrome::kChromeUIBugReportHost)
+ return &NewDOMUI<BugReportUI>;
if (url.host() == chrome::kChromeUIDevToolsHost)
return &NewDOMUI<DevToolsUI>;
if (url.host() == chrome::kChromeUIDownloadsHost)
diff --git a/chrome/browser/dom_ui/dom_ui_screenshot_source.cc b/chrome/browser/dom_ui/dom_ui_screenshot_source.cc
new file mode 100644
index 0000000..3810f4d
--- /dev/null
+++ b/chrome/browser/dom_ui/dom_ui_screenshot_source.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2009 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/dom_ui/dom_ui_screenshot_source.h"
+
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/ref_counted_memory.h"
+#include "base/task.h"
+#include "base/thread.h"
+#include "base/waitable_event.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/url_constants.h"
+#include "gfx/codec/jpeg_codec.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+static const char kCurrentScreenshot[] = "current";
+#if defined(OS_CHROMEOS)
+static const char kSavedScreenshots[] = "saved/";
+#endif
+
+static const char kScreenshotsRelativePath[] = "/Screenshots/";
+
+#if defined(OS_CHROMEOS)
+// Read the file from the screenshots directory into the read_bytes vector.
+void ReadScreenshot(const std::string& filename,
+ std::vector<unsigned char>* read_bytes,
+ base::WaitableEvent* read_complete) {
+ read_bytes->clear();
+
+ FilePath fileshelf_path;
+ if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &fileshelf_path)) {
+ read_complete->Signal();
+ return;
+ }
+
+ FilePath file(fileshelf_path.value() + std::string(kScreenshotsRelativePath) +
+ filename);
+
+ int64 file_size = 0;
+ if (!file_util::GetFileSize(file, &file_size)) {
+ read_complete->Signal();
+ return;
+ }
+
+ // expand vector to file size
+ read_bytes->resize(file_size);
+ // read file into the vector
+ int bytes_read = 0;
+ if (!(bytes_read = file_util::ReadFile(file,
+ reinterpret_cast<char*>(
+ &read_bytes->front()),
+ static_cast<int>(file_size))))
+ read_bytes->clear();
+
+ // We're done, if successful, read_bytes will have the data
+ // otherwise, it'll be empty.
+ read_complete->Signal();
+}
+
+// Get a saved screenshot - read on the FILE thread.
+std::vector<unsigned char> GetSavedScreenshot(std::string filename) {
+ base::WaitableEvent read_complete(true, false);
+ std::vector<unsigned char> bytes;
+ ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
+ NewRunnableFunction(&ReadScreenshot, filename,
+ &bytes, &read_complete));
+ read_complete.Wait();
+ return bytes;
+}
+#endif
+
+std::vector<unsigned char> DOMUIScreenshotSource::GetScreenshot(
+ const std::string& path) {
+ if (path == kCurrentScreenshot) {
+ return current_screenshot_;
+#if defined(OS_CHROMEOS)
+ } else if (path.compare(0, strlen(kSavedScreenshots),
+ kSavedScreenshots) == 0) {
+ // Split the saved screenshot filename from the path
+ std::string filename = path.substr(strlen(kSavedScreenshots));
+
+ return GetSavedScreenshot(filename);
+#endif
+ } else {
+ std::vector<unsigned char> ret;
+ // TODO(rkc): Weird vc bug, return std::vector<unsigned char>() causes
+ // the object assigned to the return value of this function magically
+ // change it's address 0x0; look into this eventually.
+ return ret;
+ }
+}
+
+DOMUIScreenshotSource::DOMUIScreenshotSource(
+ std::vector<unsigned char>* current_screenshot)
+ : DataSource(chrome::kChromeUIScreenshotPath, MessageLoop::current()) {
+ // Setup the last screenshot taken.
+ if (current_screenshot)
+ current_screenshot_ = *current_screenshot;
+ else
+ current_screenshot_.clear();
+}
+
+void DOMUIScreenshotSource::StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id) {
+ SendResponse(request_id, new RefCountedBytes(GetScreenshot(path)));
+}
diff --git a/chrome/browser/dom_ui/dom_ui_screenshot_source.h b/chrome/browser/dom_ui/dom_ui_screenshot_source.h
new file mode 100644
index 0000000..be4e280
--- /dev/null
+++ b/chrome/browser/dom_ui/dom_ui_screenshot_source.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2009 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_DOM_UI_DOM_UI_SCREENSHOT_SOURCE_H_
+#define CHROME_BROWSER_DOM_UI_DOM_UI_SCREENSHOT_SOURCE_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
+#include "chrome/browser/dom_ui/html_dialog_ui.h"
+
+// ScreenshotSource is the data source that serves screenshots (saved
+// or current) to the bug report html ui
+class DOMUIScreenshotSource : public ChromeURLDataManager::DataSource {
+ public:
+ explicit DOMUIScreenshotSource(
+ std::vector<unsigned char>* current_screenshot);
+
+ // Called when the network layer has requested a resource underneath
+ // the path we registered.
+ virtual void StartDataRequest(const std::string& path,
+ bool is_off_the_record,
+ int request_id);
+
+ virtual std::string GetMimeType(const std::string&) const {
+ // We need to explicitly return a mime type, otherwise if the user tries to
+ // drag the image they get no extension.
+ return "image/png";
+ }
+
+ std::vector<unsigned char> GetScreenshot(const std::string& path);
+
+ private:
+ ~DOMUIScreenshotSource() {}
+
+// scoped_refptr<RefCountedBytes> current_screenshot_;
+ std::vector<unsigned char> current_screenshot_;
+ DISALLOW_COPY_AND_ASSIGN(DOMUIScreenshotSource);
+};
+
+#endif // CHROME_BROWSER_DOM_UI_DOM_UI_SCREENSHOT_SOURCE_H_
diff --git a/chrome/browser/resources/bug_report.css b/chrome/browser/resources/bug_report.css
new file mode 100644
index 0000000..09230c1
--- /dev/null
+++ b/chrome/browser/resources/bug_report.css
@@ -0,0 +1,99 @@
+.bug-report-label {
+ text-align: start;
+ vertical-align: text-top;
+}
+
+.bug-report-text {
+ width: 40em;
+ resize: none;
+}
+
+.bug-report-button {
+ width: 8em;
+}
+
+hr {
+ border: none;
+ height: 1px;
+ background: #cccccc;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ width: 33.5em;
+}
+
+.thumbnail-list {
+ -webkit-margin-start: 1em;
+ width: 33.5em;
+ display: block;
+ margin-top: 0.5em;
+ margin-bottom: 1em;
+}
+
+.image-thumbnail-container {
+ display: inline-block;
+ border: 2px solid white;
+ -webkit-border-radius: 3px;
+ z-index: 0;
+}
+
+.image-thumbnail-container-selected {
+ display: inline-block;
+ border: 2px solid green;
+ -webkit-border-radius: 3px;
+ z-index: 0;
+}
+
+.image-thumbnail-container:hover {
+ border: 2px solid #B8DAB0;
+ z-index: 0;
+}
+
+.image-popup {
+ width: 50%;
+}
+
+.image-thumbnail {
+ position: relative;
+ z-index: 1;
+ display: inline-block;
+ padding: 0px;
+ border: 2px solid white;
+}
+
+.image-thumbnail:hover {
+ z-index: 2;
+}
+
+.image-thumbnail div {
+ display: none;
+}
+
+.image-thumbnail img {
+ display: block;
+ width: 75px;
+}
+
+.image-thumbnail:hover div {
+ display: block;
+ position: absolute;
+ top: 130%;
+ left:0;
+ padding: 1px;
+ border: 1px dashed blue;
+ background-color: transparent;
+ text-align: center
+}
+
+.image-thumbnail:hover div img {
+ position: absolute;
+ width: 400px;
+}
+
+th {
+ padding-top: 10px;
+ color: #233478;
+}
+
+body {
+ -webkit-user-select: none;
+}
diff --git a/chrome/browser/resources/bug_report.html b/chrome/browser/resources/bug_report.html
new file mode 100644
index 0000000..c3b53ce
--- /dev/null
+++ b/chrome/browser/resources/bug_report.html
@@ -0,0 +1,135 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection;">
+<head>
+<meta charset="utf-8"/>
+<title i18n-content="title"></title>
+<link rel="stylesheet" href="bug_report.css"/>
+
+<script src="shared/js/local_strings.js"></script>
+<script src="shared/js/util.js"></script>
+<script src="bug_report.js"></script>
+<script>
+
+///////////////////////////////////////////////////////////////////////////////
+// Document Functions:
+/**
+ * Window onload handler, sets up the page.
+ */
+function load() {
+ // textContent on description-text textarea seems to default
+ // to several spaces, this resets it to empty.
+ $('description-text').textContent = '';
+
+ $('current-screenshot').nextSibling.textContent =
+ localStrings.getString('currentscreenshots');
+ $('no-screenshot').nextSibling.textContent =
+ localStrings.getString('noscreenshot');
+
+ // Get a list of issues that we allow the user to select from.
+ // Note, the order and the issues types themselves are different
+ // between Chromium and Chromium OS, so this code needs to be
+ // maintained individually between the bug_report.html and
+ // bug_report_cros.html files.
+ var issueTypeText = [];
+ issueTypeText[0] = localStrings.getString('issue-choose');
+ issueTypeText[1] = localStrings.getString('issue-page-formatting');
+ issueTypeText[2] = localStrings.getString('issue-page-load');
+ issueTypeText[3] = localStrings.getString('issue-plugins');
+ issueTypeText[4] = localStrings.getString('issue-tabs');
+ issueTypeText[5] = localStrings.getString('issue-sync');
+ issueTypeText[6] = localStrings.getString('issue-crashes');
+ issueTypeText[7] = localStrings.getString('issue-extensions');
+ issueTypeText[8] = localStrings.getString('issue-phishing');
+ issueTypeText[9] = localStrings.getString('issue-other');
+
+ // Add all the issues to the selection box.
+ for (var i = 0; i < issueTypeText.length; i++) {
+ var option = document.createElement('option');
+ option.className = 'bug-report-text';
+ option.textContent = issueTypeText[i];
+ $('issue-with-combo').add(option);
+ }
+
+ chrome.send('getDialogDefaults', []);
+ chrome.send('refreshScreenshots', []);
+};
+
+function setupScreenshots(screenshots) {
+ if (screenshots.length > 0)
+ addScreenshot('current-screenshots', screenshots[0]);
+}
+
+function setupDialogDefaults(defaults) {
+ if (defaults.length > 0)
+ $('page-url-text').value = defaults[0];
+}
+
+window.addEventListener('DOMContentLoaded', load);
+</script>
+</head>
+<body>
+<table>
+ <!-- Issue type dropdown -->
+ <tr>
+ <th id="issue-with" class="bug-report-label" i18n-content="issue-with">
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <select id="issue-with-combo" class="bug-report-text">
+ </select>
+ </td>
+ </tr>
+ <!-- Page URL text box -->
+ <tr>
+ <th colspan="2" id="page-url" class="bug-report-label"
+ i18n-content="page-url">
+ </th>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <input id='page-url-text' maxlength=200 class="bug-report-text">
+ </td>
+ </tr>
+ <!-- Description -->
+ <tr>
+ <th id="description" colspan="2" class="bug-report-label"
+ i18n-content="description">
+ </th>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <textarea id='description-text' rows="10" class="bug-report-text">
+ </textarea>
+ </td>
+ </tr>
+ <!-- Screenshot radio buttons -->
+ <tr>
+ <th id="screenshot" class="bug-report-label" i18n-content="screenshot">
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <input id="no-screenshot" type="radio" name="screenshot-group"
+ value="none" onclick="noneSelected()">
+ <br>
+ <input id="current-screenshot" type="radio" name="screenshot-group"
+ value="current" checked onclick="currentSelected()">
+ <br>
+ <div id="current-screenshots" class="thumbnail-list">
+ </div>
+ </td>
+ </tr>
+ <!-- Buttons -->
+ <tr>
+ <td>
+ <hr>
+ <input id='send-report-button' type="submit" class="bug-report-button"
+ i18n-values="value:send-report" onclick="sendReport()">
+ <input id='cancel-button' type="submit" class="bug-report-button"
+ i18n-values="value:cancel" onclick="cancel()">
+ </td>
+ </tr>
+</table>
+</body>
+</html>
diff --git a/chrome/browser/resources/bug_report.js b/chrome/browser/resources/bug_report.js
new file mode 100644
index 0000000..508a954
--- /dev/null
+++ b/chrome/browser/resources/bug_report.js
@@ -0,0 +1,152 @@
+// Copyright (c) 2010 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.
+
+// Constants.
+var FEEDBACK_LANDING_PAGE =
+ 'http://www.google.com/support/chrome/go/feedback_confirmation'
+
+var selectedThumbnailDivId = '';
+var selectedThumbnailId = '';
+var selectedImageUrl;
+
+var savedThumbnailIds = [];
+savedThumbnailIds['current-screenshots'] = '';
+savedThumbnailIds['saved-screenshots'] = '';
+
+var localStrings = new LocalStrings();
+
+/**
+ * Selects an image thumbnail in the specified div.
+ */
+function selectImage(divId, thumbnailId) {
+ var thumbnailDivs = $(divId).children;
+ selectedThumbnailDivId = divId;
+ for (var i = 0; i < thumbnailDivs.length; i++) {
+ // If the the current div matches the thumbnail id provided,
+ // or there is no thumbnail id given, and we're at the first thumbnail.
+ if ((thumbnailDivs[i].id == thumbnailId) || (!thumbnailId && !i)) {
+ thumbnailDivs[i].className = 'image-thumbnail-container-selected';
+ selectedThumbnailId = thumbnailId;
+ savedThumbnailIds[divId] = thumbnailId;
+ } else {
+ thumbnailDivs[i].className = 'image-thumbnail-container';
+ }
+ }
+}
+
+/**
+ * Adds an image thumbnail to the specified div.
+ */
+function addScreenshot(divId, screenshot) {
+ var thumbnailDiv = document.createElement('div');
+ thumbnailDiv.className = 'image-thumbnail-container';
+
+ thumbnailDiv.id = divId + '-thumbnailDiv-' + $(divId).children.length;
+ thumbnailDiv.onclick = function() {
+ selectImage(divId, thumbnailDiv.id);
+ };
+
+ var innerDiv = document.createElement('div');
+ innerDiv.className = 'image-thumbnail';
+
+ var thumbnail = document.createElement('img');
+ thumbnail.id = thumbnailDiv.id + '-image';
+ thumbnail.src = screenshot;
+ innerDiv.appendChild(thumbnail);
+
+ var largeImage = document.createElement('img');
+ largeImage.src = screenshot;
+
+ var popupDiv = document.createElement('div');
+ popupDiv.appendChild(largeImage);
+ innerDiv.appendChild(popupDiv);
+
+ thumbnailDiv.appendChild(innerDiv);
+ $(divId).appendChild(thumbnailDiv);
+
+ if (!selectedThumbnailId)
+ selectImage(divId, thumbnailDiv.id);
+}
+
+/**
+ * Send's the report; after the report is sent, we need to be redirected to
+ * the landing page, but we shouldn't be able to navigate back, hence
+ * we open the landing page in a new tab and sendReport closes this tab.
+ */
+function sendReport() {
+ if (!$('issue-with-combo').selectedIndex) {
+ alert(localStrings.getString('no-issue-selected'));
+ return false;
+ }
+
+ var imagePath = '';
+ if (selectedThumbnailId)
+ imagePath = $(selectedThumbnailId + '-image').src;
+
+ // Note, categories are based from 1 in our protocol buffers, so no
+ // adjustment is needed on selectedIndex.
+ var reportArray = [String($('issue-with-combo').selectedIndex),
+ $('page-url-text').value,
+ $('description-text').value,
+ imagePath];
+
+ // Add chromeos data if it exists.
+ if ($('user-email-text') && $('sys-info-checkbox')) {
+ reportArray = reportArray.concat([$('user-email-text').value,
+ String($('sys-info-checkbox').checked)]);
+ }
+
+ // open the landing page in a new tab, sendReport will close this one.
+ window.open(FEEDBACK_LANDING_PAGE, '_blank');
+ chrome.send('sendReport', reportArray);
+ return true;
+}
+
+function cancel() {
+ chrome.send('cancel', []);
+ return true;
+}
+
+/**
+ * Select the current screenshots div, restoring the image that was
+ * selected when we had this div open previously.
+ */
+function currentSelected() {
+ $('current-screenshots').style.display = 'block';
+ if ($('saved-screenshots'))
+ $('saved-screenshots').style.display = 'none';
+
+ if (selectedThumbnailDivId != 'current-screenshots')
+ selectImage('current-screenshots',
+ savedThumbnailIds['current-screenshots']);
+
+ return true;
+}
+
+/**
+ * Select the saved screenshots div, restoring the image that was
+ * selected when we had this div open previously.
+ */
+function savedSelected() {
+ $('current-screenshots').style.display = 'none';
+ $('saved-screenshots').style.display = 'block';
+
+ if (selectedThumbnailDivId != 'saved-screenshots')
+ selectImage('saved-screenshots', savedThumbnailIds['saved-screenshots']);
+
+ return true;
+}
+
+/**
+ * Unselect all screenshots divs.
+ */
+function noneSelected() {
+ $('current-screenshots').style.display = 'none';
+ if ($('saved-screenshots'))
+ $('saved-screenshots').style.display = 'none';
+
+ selectedThumbnailDivId = '';
+ selectedThumbnailId = '';
+ return true;
+}
diff --git a/chrome/browser/resources/bug_report_cros.html b/chrome/browser/resources/bug_report_cros.html
new file mode 100644
index 0000000..d001c7e
--- /dev/null
+++ b/chrome/browser/resources/bug_report_cros.html
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection;">
+<head>
+<meta charset="utf-8"/>
+<title i18n-content="title"></title>
+<link rel="stylesheet" href="bug_report.css"/>
+
+<script src="shared/js/local_strings.js"></script>
+<script src="shared/js/util.js"></script>
+<script src="bug_report.js"></script>
+<script>
+
+///////////////////////////////////////////////////////////////////////////////
+// Document Functions:
+/**
+ * Window onload handler, sets up the page.
+ */
+function load() {
+ // textContent on description-text textarea seems to default
+ // to several spaces, this resets it to empty.
+ $('description-text').textContent = '';
+
+ $('current-screenshot').nextSibling.textContent =
+ localStrings.getString('currentscreenshots');
+ $('saved-screenshot').nextSibling.textContent =
+ localStrings.getString('savedscreenshots');
+ $('no-screenshot').nextSibling.textContent =
+ localStrings.getString('noscreenshot');
+
+ // Get a list of issues that we allow the user to select from.
+ // Note, the order and the issues types themselves are different
+ // between Chromium and Chromium OS, so this code needs to be
+ // maintained individually between the bug_report.html and
+ // bug_report_cros.html files.
+ var issueTypeText = [];
+ issueTypeText[0] = localStrings.getString('issue-choose');
+ issueTypeText[1] = localStrings.getString('issue-connectivity');
+ issueTypeText[2] = localStrings.getString('issue-sync');
+ issueTypeText[3] = localStrings.getString('issue-crashes');
+ issueTypeText[4] = localStrings.getString('issue-page-formatting');
+ issueTypeText[5] = localStrings.getString('issue-extensions');
+ issueTypeText[6] = localStrings.getString('issue-standby');
+ issueTypeText[7] = localStrings.getString('issue-phishing');
+ issueTypeText[8] = localStrings.getString('issue-other');
+
+ // Add all the issues to the selection box.
+ for (var i = 0; i < issueTypeText.length; i++) {
+ var option = document.createElement('option');
+ option.className = 'bug-report-text';
+ option.textContent = issueTypeText[i];
+ $('issue-with-combo').add(option);
+ }
+
+ chrome.send('getDialogDefaults', []);
+ chrome.send('refreshScreenshots', []);
+};
+
+function setupScreenshots(screenshots) {
+ if (screenshots.length > 1) {
+ currentScreenshot = screenshots[0];
+ addScreenshot('current-screenshots', currentScreenshot);
+
+ savedScreenshots = screenshots[1];
+ for (i = 0; i < savedScreenshots.length; ++i)
+ addScreenshot('saved-screenshots', savedScreenshots[i]);
+ }
+}
+
+function setupDialogDefaults(defaults) {
+ if (defaults.length > 2) {
+ $('page-url-text').value = defaults[0];
+ $('sysinfo-url').href = defaults[1];
+ $('user-email-text').value = defaults[2];
+ }
+}
+
+window.addEventListener('DOMContentLoaded', load);
+</script>
+</head>
+<body>
+<table>
+ <!-- Issue type dropdown -->
+ <tr>
+ <th id="issue-with" class="bug-report-label" i18n-content="issue-with">
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <select id="issue-with-combo" class="bug-report-text">
+ </select>
+ </td>
+ </tr>
+ <!-- Page URL text box -->
+ <tr>
+ <th colspan="2" id="page-url" class="bug-report-label"
+ i18n-content="page-url">
+ </th>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <input id='page-url-text' maxlength=200 class="bug-report-text">
+ </td>
+ </tr>
+ <!-- Description -->
+ <tr>
+ <th id="description" colspan="2" class="bug-report-label"
+ i18n-content="description">
+ </th>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <textarea id='description-text' rows="10" class="bug-report-text">
+ </textarea>
+ </td>
+ </tr>
+ <!-- System Information checkbox -->
+ <tr>
+ <td>
+ <input id="sys-info-checkbox" type="checkbox" value="sysinfo" checked>
+ <span id="sysinfo-label"></span> <a href='about:blank' id="sysinfo-url"
+ target="_blank" i18n-content="sysinfo">></a>
+ </td>
+ </tr>
+ <!-- Page URL text box -->
+ <tr>
+ <th id="user-email" class="bug-report-label" i18n-content="user-email">
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <input id='user-email-text' maxlength=200 class="bug-report-text">
+ </td>
+ </tr>
+ <!-- Screenshot radio buttons -->
+ <tr>
+ <th id="screenshot" class="bug-report-label" i18n-content="screenshot">
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <input id="no-screenshot" type="radio" name="screenshot-group"
+ value="none" onclick="noneSelected()">
+ <br>
+ <input id="saved-screenshot" type="radio" name="screenshot-group"
+ value="saved" onclick="savedSelected()">
+ <br>
+ <div id="saved-screenshots" style="display: none;"
+ class="thumbnail-list">
+ </div>
+ <input id="current-screenshot" type="radio" name="screenshot-group"
+ value="current" checked onclick="currentSelected()">
+ <br>
+ <div id="current-screenshots" class="thumbnail-list">
+ </div>
+ </td>
+ </tr>
+ <!-- Buttons -->
+ <tr>
+ <td>
+ <hr>
+ <input id='send-report-button' type="submit" class="bug-report-button"
+ i18n-values="value:send-report" onclick="sendReport()">
+ <input id='cancel-button' type="submit" class="bug-report-button"
+ i18n-values="value:cancel" onclick="cancel()">
+ </td>
+ </tr>
+</table>
+</body>
+</html>
diff --git a/chrome/browser/resources/bug_report_invalid.html b/chrome/browser/resources/bug_report_invalid.html
new file mode 100644
index 0000000..e6b1605
--- /dev/null
+++ b/chrome/browser/resources/bug_report_invalid.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<title i18n-content="title"></title>
+<body onselectstart='return false'>
+Invalid BugReport options - please check.
+</body>
+</html>
diff --git a/chrome/browser/userfeedback/proto/chrome.proto b/chrome/browser/userfeedback/proto/chrome.proto
new file mode 100644
index 0000000..11b8eff
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/chrome.proto
@@ -0,0 +1,55 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+// Author: marcinm@google.com (Marcin Mikosik)
+
+syntax = "proto2";
+
+package userfeedback;
+
+// Chrome Browser and Chrome OS specific data.
+message ChromeData {
+ // Encapsulates the priorities of Buganizer issues.
+ enum ChromePlatform {
+ CHROME_OS = 1;
+ CHROME_BROWSER = 2;
+ }
+
+ // What platform has a report been sent from.
+ optional ChromePlatform chrome_platform = 1 [default = CHROME_OS];
+
+ optional ChromeOsData chrome_os_data = 2;
+
+ optional ChromeBrowserData chrome_browser_data = 3;
+}
+
+message ChromeOsData {
+ enum ChromeOsCategory {
+ CONNECTIVITY = 1;
+ SYNC = 2;
+ CRASH = 3;
+ PAGE_FORMATTING_OR_LAYOUT = 4;
+ EXTENSIONS_OR_APPS = 5;
+ STANDBY_OR_RESUME = 6;
+ PHISHING_PAGE = 7;
+ OTHER = 8;
+ }
+
+ optional ChromeOsCategory category = 1 [default = OTHER];
+}
+
+message ChromeBrowserData{
+
+ enum ChromeBrowserCategory {
+ PAGE_FORMATTING_OR_LAYOUT = 1;
+ PAGES_NOT_LOADING = 2;
+ PLUGINS = 3;
+ TABS_OR_WINDOWS = 4;
+ SYNCED_PREFERENCES = 5;
+ CRASH = 6;
+ EXTENSIONS_OR_APPS = 7;
+ PHISHING_PAGE = 8;
+ OTHER = 9;
+ }
+
+ optional ChromeBrowserCategory category = 1 [default = OTHER];
+}
+
diff --git a/chrome/browser/userfeedback/proto/common.proto b/chrome/browser/userfeedback/proto/common.proto
index 97c60fb..291e6a1 100644
--- a/chrome/browser/userfeedback/proto/common.proto
+++ b/chrome/browser/userfeedback/proto/common.proto
@@ -16,7 +16,13 @@ message CommonData {
// Description of the problem entered by user.
optional string description = 2;
optional string description_translated = 4;
- optional string source_descripton_language = 5 [ default = "en" ];
+ optional string source_description_language = 5 [ default = "en" ];
+ optional string ui_language = 6 [ default = "en_US" ];
optional string user_email = 3;
+
+ // Unique identifier of feedback report. If set than only one report
+ // with the same identifier is stored in the system.
+ // If you are not sure how to use it leave it not set.
+ optional string unique_report_identifier = 7;
};
diff --git a/chrome/browser/userfeedback/proto/extension.proto b/chrome/browser/userfeedback/proto/extension.proto
index d600f8a..71be3dc 100644
--- a/chrome/browser/userfeedback/proto/extension.proto
+++ b/chrome/browser/userfeedback/proto/extension.proto
@@ -8,6 +8,7 @@ syntax = "proto2";
package userfeedback;
import "common.proto";
+import "chrome.proto";
import "dom.proto";
import "math.proto";
import "web.proto";
@@ -64,6 +65,8 @@ message ExternalExtensionSubmit {
optional HtmlDocument html_document_structure = 5;
optional ExtensionErrors extension_errors = 13;
+
+ optional ChromeData chrome_data = 14;
};
// Sent when user hits final submit button in internal extension.
diff --git a/chrome/browser/userfeedback/proto/web.proto b/chrome/browser/userfeedback/proto/web.proto
index fb9f6af..71b0b29 100644
--- a/chrome/browser/userfeedback/proto/web.proto
+++ b/chrome/browser/userfeedback/proto/web.proto
@@ -8,7 +8,6 @@ package userfeedback;
// Data present in Web related feedbacks
import "annotations.proto";
-import "config.proto";
import "dom.proto";
import "math.proto";
diff --git a/chrome/browser/views/browser_dialogs.h b/chrome/browser/views/browser_dialogs.h
index f775d97..8affac9 100644
--- a/chrome/browser/views/browser_dialogs.h
+++ b/chrome/browser/views/browser_dialogs.h
@@ -45,6 +45,9 @@ void ShowBugReportView(views::Window* parent,
Profile* profile,
TabContents* tab);
+// Shows the "Report a problem with this page" page in a new tab
+void ShowHtmlBugReportView(views::Window* parent, Browser* browser);
+
// Shows the "Clear browsing data" dialog box. See ClearBrowsingDataView.
void ShowClearBrowsingDataView(gfx::NativeWindow parent,
Profile* profile);
diff --git a/chrome/browser/views/bug_report_view.cc b/chrome/browser/views/bug_report_view.cc
deleted file mode 100644
index 03cbc76..0000000
--- a/chrome/browser/views/bug_report_view.cc
+++ /dev/null
@@ -1,627 +0,0 @@
-// Copyright (c) 2010 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/views/bug_report_view.h"
-
-#include <string>
-#include <vector>
-
-#include "app/combobox_model.h"
-#include "app/l10n_util.h"
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/file_version_info.h"
-#include "base/path_service.h"
-#include "base/utf_string_conversions.h"
-#include "base/waitable_event.h"
-#include "chrome/browser/bug_report_util.h"
-#include "chrome/browser/pref_service.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/chrome_thread.h"
-#include "chrome/browser/safe_browsing/safe_browsing_util.h"
-#include "chrome/browser/tab_contents/navigation_controller.h"
-#include "chrome/browser/tab_contents/navigation_entry.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/net/url_fetcher.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
-#include "grit/locale_settings.h"
-#include "net/base/escape.h"
-#include "unicode/locid.h"
-#include "views/controls/button/checkbox.h"
-#include "views/controls/label.h"
-#include "views/grid_layout.h"
-#include "views/standard_layout.h"
-#include "views/widget/widget.h"
-#include "views/window/client_view.h"
-#include "views/window/window.h"
-
-#if defined(OS_LINUX)
-#include "app/x11_util.h"
-#else
-#include "app/win_util.h"
-#endif
-
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/login/user_manager.h"
-#endif
-
-using views::ColumnSet;
-using views::GridLayout;
-
-// Report a bug data version.
-static const int kBugReportVersion = 1;
-static const int kScreenImageRadioGroup = 2;
-static const char kScreenshotsRelativePath[] = "/Screenshots";
-static const char kScreenshotPattern[] = "*.png";
-
-// Number of lines description field can display at one time.
-static const int kDescriptionLines = 5;
-
-class BugReportComboBoxModel : public ComboboxModel {
- public:
- BugReportComboBoxModel() {}
-
- // ComboboxModel interface.
- virtual int GetItemCount() {
- return BugReportUtil::OTHER_PROBLEM + 1;
- }
-
- virtual std::wstring GetItemAt(int index) {
- return GetItemAtIndex(index);
- }
-
- static std::wstring GetItemAtIndex(int index) {
-#if defined(OS_CHROMEOS)
- switch (index) {
- case BugReportUtil::CONNECTIVITY_ISSUE:
- return l10n_util::GetString(IDS_BUGREPORT_CONNECTIVITY_ISSUE);
- case BugReportUtil::SYNC_ISSUE:
- return l10n_util::GetString(IDS_BUGREPORT_SYNC_ISSUE);
- case BugReportUtil::CRASH_ISSUE:
- return l10n_util::GetString(IDS_BUGREPORT_CRASH_ISSUE);
- case BugReportUtil::PAGE_FORMATTING:
- return l10n_util::GetString(IDS_BUGREPORT_PAGE_FORMATTING);
- case BugReportUtil::EXTENSION_ISSUE:
- return l10n_util::GetString(IDS_BUGREPORT_EXTENSION_ISSUE);
- case BugReportUtil::SUSPEND_ISSUE:
- return l10n_util::GetString(IDS_BUGREPORT_SUSPEND_ISSUE);
- case BugReportUtil::PHISHING_PAGE:
- return l10n_util::GetString(IDS_BUGREPORT_PHISHING_PAGE);
- case BugReportUtil::OTHER_PROBLEM:
- return l10n_util::GetString(IDS_BUGREPORT_OTHER_PROBLEM);
- default:
- NOTREACHED();
- return std::wstring();
- }
-#else
- switch (index) {
- case BugReportUtil::PAGE_WONT_LOAD:
- return l10n_util::GetString(IDS_BUGREPORT_PAGE_WONT_LOAD);
- case BugReportUtil::PAGE_LOOKS_ODD:
- return l10n_util::GetString(IDS_BUGREPORT_PAGE_LOOKS_ODD);
- case BugReportUtil::PHISHING_PAGE:
- return l10n_util::GetString(IDS_BUGREPORT_PHISHING_PAGE);
- case BugReportUtil::CANT_SIGN_IN:
- return l10n_util::GetString(IDS_BUGREPORT_CANT_SIGN_IN);
- case BugReportUtil::CHROME_MISBEHAVES:
- return l10n_util::GetString(IDS_BUGREPORT_CHROME_MISBEHAVES);
- case BugReportUtil::SOMETHING_MISSING:
- return l10n_util::GetString(IDS_BUGREPORT_SOMETHING_MISSING);
- case BugReportUtil::BROWSER_CRASH:
- return l10n_util::GetString(IDS_BUGREPORT_BROWSER_CRASH);
- case BugReportUtil::OTHER_PROBLEM:
- return l10n_util::GetString(IDS_BUGREPORT_OTHER_PROBLEM);
- default:
- NOTREACHED();
- return std::wstring();
- }
-#endif
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BugReportComboBoxModel);
-};
-
-namespace {
-
-#if defined(OS_CHROMEOS)
-class LastScreenshotTask : public Task {
- public:
- LastScreenshotTask(std::string* image_str,
- base::WaitableEvent* task_waitable)
- : image_str_(image_str),
- task_waitable_(task_waitable) {
- }
-
- private:
- void Run() {
- FilePath fileshelf_path;
- // TODO(rkc): Change this to use FilePath.Append() once the cros
- // issue with with it is fixed
- if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
- &fileshelf_path)) {
- *image_str_ = "";
- task_waitable_->Signal();
- }
-
- FilePath screenshots_path(fileshelf_path.value() +
- std::string(kScreenshotsRelativePath));
- file_util::FileEnumerator screenshots(screenshots_path, false,
- file_util::FileEnumerator::FILES,
- std::string(kScreenshotPattern));
- FilePath screenshot = screenshots.Next();
- FilePath latest("");
- time_t last_mtime = 0;
- while (!screenshot.empty()) {
- file_util::FileEnumerator::FindInfo info;
- screenshots.GetFindInfo(&info);
- if (info.stat.st_mtime > last_mtime) {
- last_mtime = info.stat.st_mtime;
- latest = screenshot;
- }
- screenshot = screenshots.Next();
- }
-
- if (!file_util::ReadFileToString(latest, image_str_))
- *image_str_ = "";
- task_waitable_->Signal();
- }
- private:
- std::string* image_str_;
- base::WaitableEvent* task_waitable_;
-};
-#endif
-
-bool GetLastScreenshot(std::string* image_str) {
-#if defined(OS_CHROMEOS)
- base::WaitableEvent task_waitable(true, false);
- ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
- new LastScreenshotTask(image_str, &task_waitable));
- task_waitable.Wait();
- if (*image_str == "")
- return false;
- else
- return true;
-#else
- return false;
-#endif
-}
-
-} // namespace
-
-namespace browser {
-
-// Global "display this dialog" function declared in browser_dialogs.h.
-void ShowBugReportView(views::Window* parent,
- Profile* profile,
- TabContents* tab) {
- BugReportView* view = new BugReportView(profile, tab);
-
- // Get the size of the parent window to capture screenshot dimensions
- gfx::Rect screen_size = parent->GetBounds();
- view->set_screen_size(screen_size);
-
- // Grab an exact snapshot of the window that the user is seeing (i.e. as
- // rendered--do not re-render, and include windowed plugins).
- std::vector<unsigned char> *screenshot_png = new std::vector<unsigned char>;
-
-#if defined(OS_LINUX)
- x11_util::GrabWindowSnapshot(parent->GetNativeWindow(), screenshot_png);
-#else
- win_util::GrabWindowSnapshot(parent->GetNativeWindow(), screenshot_png);
-#endif
-
- // The BugReportView takes ownership of the image data, and will dispose of
- // it in its destructor
- view->set_captured_image(screenshot_png);
-
-#if defined(OS_CHROMEOS)
- // Get last screenshot taken
- std::string image_str;
- bool have_last_image = false;
- if (GetLastScreenshot(&image_str)) {
- // reuse screenshot_png; previous pointer now owned by BugReportView
- screenshot_png = new std::vector<unsigned char>(image_str.begin(),
- image_str.end());
- have_last_image = true;
- } else {
- // else set it to be an empty vector
- screenshot_png = new std::vector<unsigned char>;
- }
- view->set_last_image(screenshot_png);
-
- // Create and show the dialog
- views::Window::CreateChromeWindow(parent->GetNativeWindow(), gfx::Rect(),
- view)->Show();
- if (!have_last_image)
- view->DisableLastImageRadio();
-#endif
-}
-
-} // namespace browser
-
-// BugReportView - create and submit a bug report from the user.
-// This is separate from crash reporting, which is handled by Breakpad.
-BugReportView::BugReportView(Profile* profile, TabContents* tab)
- : include_page_source_checkbox_(NULL),
- include_page_image_checkbox_(NULL),
- profile_(profile),
- tab_(tab),
- problem_type_(0) {
- DCHECK(profile);
- SetupControl();
-
- // We want to use the URL of the current committed entry (the current URL may
- // actually be the pending one).
- if (tab->controller().GetActiveEntry()) {
- page_url_text_->SetText(UTF8ToUTF16(
- tab->controller().GetActiveEntry()->url().spec()));
- }
-
-#if defined(OS_CHROMEOS)
- // Get and set the gaia e-mail
- chromeos::UserManager* manager = chromeos::UserManager::Get();
- if (!manager) {
- user_email_text_->SetText(UTF8ToUTF16(std::string("")));
- } else {
- const std::string& email = manager->logged_in_user().email();
- user_email_text_->SetText(UTF8ToUTF16(email));
- if (!email.empty())
- user_email_text_->SetEnabled(false);
- }
-#endif
-
- // Retrieve the application version info.
- scoped_ptr<FileVersionInfo> version_info(chrome::GetChromeVersionInfo());
- if (version_info.get()) {
- version_ = version_info->product_name() + L" - " +
- version_info->file_version() +
- L" (" + version_info->last_change() + L")";
- }
-
-
- FilePath tmpfilename;
-
-#if defined(OS_CHROMEOS)
- chromeos::SyslogsLibrary* syslogs_lib =
- chromeos::CrosLibrary::Get()->GetSyslogsLibrary();
- if (syslogs_lib) {
- sys_info_.reset(syslogs_lib->GetSyslogs(&tmpfilename));
- }
-#endif
-}
-
-BugReportView::~BugReportView() {
-}
-
-void BugReportView::SetupControl() {
- bug_type_model_.reset(new BugReportComboBoxModel);
-
- // Adds all controls.
- bug_type_label_ = new views::Label(
- l10n_util::GetString(IDS_BUGREPORT_BUG_TYPE));
- bug_type_combo_ = new views::Combobox(bug_type_model_.get());
- bug_type_combo_->set_listener(this);
- bug_type_combo_->SetAccessibleName(bug_type_label_->GetText());
-
- page_title_label_ = new views::Label(
- l10n_util::GetString(IDS_BUGREPORT_REPORT_PAGE_TITLE));
- page_title_text_ = new views::Label(UTF16ToWideHack(tab_->GetTitle()));
- page_url_label_ = new views::Label(
- l10n_util::GetString(IDS_BUGREPORT_REPORT_URL_LABEL));
- // page_url_text_'s text (if any) is filled in after dialog creation.
- page_url_text_ = new views::Textfield;
- page_url_text_->SetController(this);
- page_url_text_->SetAccessibleName(page_url_label_->GetText());
-
-#if defined(OS_CHROMEOS)
- user_email_label_ = new views::Label(
- l10n_util::GetString(IDS_BUGREPORT_USER_EMAIL_LABEL));
- // user_email_text_'s text (if any) is filled in after dialog creation.
- user_email_text_ = new views::Textfield;
- user_email_text_->SetController(this);
- user_email_text_->SetAccessibleName(user_email_label_->GetText());
-#endif
-
- description_label_ = new views::Label(
- l10n_util::GetString(IDS_BUGREPORT_DESCRIPTION_LABEL));
- description_text_ =
- new views::Textfield(views::Textfield::STYLE_MULTILINE);
- description_text_->SetHeightInLines(kDescriptionLines);
- description_text_->SetAccessibleName(description_label_->GetText());
-
- include_page_source_checkbox_ = new views::Checkbox(
- l10n_util::GetString(IDS_BUGREPORT_INCLUDE_PAGE_SOURCE_CHKBOX));
- include_page_source_checkbox_->SetChecked(true);
-
-#if defined(OS_CHROMEOS)
- include_last_screen_image_radio_ = new views::RadioButton(
- l10n_util::GetString(IDS_BUGREPORT_INCLUDE_LAST_SCREEN_IMAGE),
- kScreenImageRadioGroup);
-
- include_new_screen_image_radio_ = new views::RadioButton(
- l10n_util::GetString(IDS_BUGREPORT_INCLUDE_NEW_SCREEN_IMAGE),
- kScreenImageRadioGroup);
-
- include_no_screen_image_radio_ = new views::RadioButton(
- l10n_util::GetString(IDS_BUGREPORT_INCLUDE_NO_SCREEN_IMAGE),
- kScreenImageRadioGroup);
-
- system_information_url_control_ = new views::Link(
- l10n_util::GetString(IDS_BUGREPORT_SYSTEM_INFORMATION_URL_TEXT));
- system_information_url_control_->SetController(this);
-
- include_new_screen_image_radio_->SetChecked(true);
-#endif
- include_page_image_checkbox_ = new views::Checkbox(
- l10n_util::GetString(IDS_BUGREPORT_INCLUDE_PAGE_IMAGE_CHKBOX));
- include_page_image_checkbox_->SetChecked(true);
-
- // Arranges controls by using GridLayout.
- const int column_set_id = 0;
- GridLayout* layout = CreatePanelGridLayout(this);
- SetLayoutManager(layout);
- ColumnSet* column_set = layout->AddColumnSet(column_set_id);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 0,
- GridLayout::USE_PREF, 0, 0);
- column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing * 2);
- column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
- GridLayout::USE_PREF, 0, 0);
-
- // Page Title and text.
- layout->StartRow(0, column_set_id);
- layout->AddView(page_title_label_);
- layout->AddView(page_title_text_, 1, 1, GridLayout::LEADING,
- GridLayout::FILL);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- // Bug type and combo box.
- layout->StartRow(0, column_set_id);
- layout->AddView(bug_type_label_, 1, 1, GridLayout::LEADING, GridLayout::FILL);
- layout->AddView(bug_type_combo_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- // Page URL and text field.
- layout->StartRow(0, column_set_id);
- layout->AddView(page_url_label_);
- layout->AddView(page_url_text_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- // Description label and text field.
- layout->StartRow(0, column_set_id);
- layout->AddView(description_label_, 1, 1, GridLayout::LEADING,
- GridLayout::LEADING);
- layout->AddView(description_text_, 1, 1, GridLayout::FILL,
- GridLayout::LEADING);
-#if defined(OS_CHROMEOS)
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- // Page URL and text field.
- layout->StartRow(0, column_set_id);
- layout->AddView(user_email_label_);
- layout->AddView(user_email_text_);
-#endif
- layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
-
- // Checkboxes.
- // The include page source checkbox is hidden until we can make it work.
- // layout->StartRow(0, column_set_id);
- // layout->SkipColumns(1);
- // layout->AddView(include_page_source_checkbox_);
- // layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- layout->StartRow(0, column_set_id);
- layout->SkipColumns(1);
-#if defined(OS_CHROMEOS)
- // Radio boxes to select last screen shot or,
-
- // new screenshot
- layout->AddView(include_new_screen_image_radio_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- // last screenshot taken
- layout->StartRow(0, column_set_id);
- layout->SkipColumns(1);
- layout->AddView(include_last_screen_image_radio_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- // no screenshot
- layout->StartRow(0, column_set_id);
- layout->SkipColumns(1);
- layout->AddView(include_no_screen_image_radio_);
- layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
-
- layout->StartRow(0, column_set_id);
- layout->SkipColumns(1);
- layout->AddView(system_information_url_control_, 1, 1, GridLayout::LEADING,
- GridLayout::CENTER);
-#else
- if (include_page_image_checkbox_) {
- layout->StartRow(0, column_set_id);
- layout->SkipColumns(1);
- layout->AddView(include_page_image_checkbox_);
- }
-#endif
-
- layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
-}
-
-gfx::Size BugReportView::GetPreferredSize() {
- gfx::Size size = views::Window::GetLocalizedContentsSize(
- IDS_BUGREPORT_DIALOG_WIDTH_CHARS,
-#if defined(OS_CHROMEOS)
- IDS_CHROMEOS_BUGREPORT_DIALOG_HEIGHT_LINES);
-#else
- IDS_BUGREPORT_DIALOG_HEIGHT_LINES);
-#endif
- return size;
-}
-
-void BugReportView::UpdateReportingControls(bool is_phishing_report) {
- // page source, screen/page images, system information
- // are not needed if it's a phishing report
-
- include_page_source_checkbox_->SetEnabled(!is_phishing_report);
- include_page_source_checkbox_->SetChecked(!is_phishing_report);
-
-#if defined(OS_CHROMEOS)
- include_new_screen_image_radio_->SetEnabled(!is_phishing_report);
- if (!last_image_->empty())
- include_last_screen_image_radio_->SetEnabled(!is_phishing_report);
- include_no_screen_image_radio_->SetEnabled(!is_phishing_report);
-#else
- if (include_page_image_checkbox_) {
- include_page_image_checkbox_->SetEnabled(!is_phishing_report);
- include_page_image_checkbox_->SetChecked(!is_phishing_report);
- }
-#endif
-}
-
-void BugReportView::ItemChanged(views::Combobox* combobox,
- int prev_index,
- int new_index) {
- if (new_index == prev_index)
- return;
-
- problem_type_ = new_index;
- bool is_phishing_report = new_index == BugReportUtil::PHISHING_PAGE;
-
- description_text_->SetEnabled(!is_phishing_report);
- description_text_->SetReadOnly(is_phishing_report);
- if (is_phishing_report) {
- old_report_text_ = UTF16ToWide(description_text_->text());
- description_text_->SetText(string16());
- } else if (!old_report_text_.empty()) {
- description_text_->SetText(WideToUTF16Hack(old_report_text_));
- old_report_text_.clear();
- }
-
- UpdateReportingControls(is_phishing_report);
- GetDialogClientView()->UpdateDialogButtons();
-}
-
-void BugReportView::ContentsChanged(views::Textfield* sender,
- const string16& new_contents) {
-}
-
-bool BugReportView::HandleKeystroke(views::Textfield* sender,
- const views::Textfield::Keystroke& key) {
- return false;
-}
-
-std::wstring BugReportView::GetDialogButtonLabel(
- MessageBoxFlags::DialogButton button) const {
- if (button == MessageBoxFlags::DIALOGBUTTON_OK) {
- if (problem_type_ == BugReportUtil::PHISHING_PAGE)
- return l10n_util::GetString(IDS_BUGREPORT_SEND_PHISHING_REPORT);
- else
- return l10n_util::GetString(IDS_BUGREPORT_SEND_REPORT);
- } else {
- return std::wstring();
- }
-}
-
-int BugReportView::GetDefaultDialogButton() const {
- return MessageBoxFlags::DIALOGBUTTON_NONE;
-}
-
-bool BugReportView::CanResize() const {
- return false;
-}
-
-bool BugReportView::CanMaximize() const {
- return false;
-}
-
-bool BugReportView::IsAlwaysOnTop() const {
- return false;
-}
-
-bool BugReportView::HasAlwaysOnTopMenu() const {
- return false;
-}
-
-bool BugReportView::IsModal() const {
- return true;
-}
-
-std::wstring BugReportView::GetWindowTitle() const {
- return l10n_util::GetString(IDS_BUGREPORT_TITLE);
-}
-
-
-bool BugReportView::Accept() {
- if (IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) {
- if (problem_type_ == BugReportUtil::PHISHING_PAGE) {
- BugReportUtil::ReportPhishing(tab_,
- UTF16ToUTF8(page_url_text_->text()));
- } else {
- char* image_data = NULL;
- size_t image_data_size = 0;
-#if defined(OS_CHROMEOS)
- if (include_new_screen_image_radio_->checked() &&
- !captured_image_->empty()) {
- image_data = reinterpret_cast<char *>(&captured_image_->front());
- image_data_size = captured_image_->size();
- } else if (include_last_screen_image_radio_->checked() &&
- !last_image_->empty()) {
- image_data = reinterpret_cast<char *>(&last_image_->front());
- image_data_size = last_image_->size();
- }
-#else
- if (include_page_image_checkbox_->checked() && captured_image_.get() &&
- !captured_image_->empty()) {
- image_data = reinterpret_cast<char *>(&captured_image_->front());
- image_data_size = captured_image_->size();
- }
-#endif
-#if defined(OS_CHROMEOS)
- BugReportUtil::SendReport(profile_,
- WideToUTF8(page_title_text_->GetText()),
- problem_type_,
- UTF16ToUTF8(page_url_text_->text()),
- UTF16ToUTF8(user_email_text_->text()),
- UTF16ToUTF8(description_text_->text()),
- image_data, image_data_size,
- screen_size_.width(), screen_size_.height(),
- WideToUTF8(bug_type_combo_->model()->GetItemAt(problem_type_)),
- sys_info_.get());
-#else
- BugReportUtil::SendReport(profile_,
- WideToUTF8(page_title_text_->GetText()),
- problem_type_,
- UTF16ToUTF8(page_url_text_->text()),
- std::string(),
- UTF16ToUTF8(description_text_->text()),
- image_data, image_data_size,
- screen_size_.width(), screen_size_.height());
-#endif
- }
- }
- return true;
-}
-
-#if defined(OS_CHROMEOS)
-void BugReportView::LinkActivated(views::Link* source,
- int event_flags) {
- GURL url;
- if (source == system_information_url_control_) {
- url = GURL(chrome::kAboutSystemURL);
- } else {
- NOTREACHED() << "Unknown link source";
- return;
- }
-
- Browser* browser = BrowserList::GetLastActive();
- if (browser)
- browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
-}
-#endif
-
-
-views::View* BugReportView::GetContentsView() {
- return this;
-}
diff --git a/chrome/browser/views/bug_report_view.h b/chrome/browser/views/bug_report_view.h
deleted file mode 100644
index da9fe41..0000000
--- a/chrome/browser/views/bug_report_view.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2010 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_VIEWS_BUG_REPORT_VIEW_H_
-#define CHROME_BROWSER_VIEWS_BUG_REPORT_VIEW_H_
-#pragma once
-
-#include "chrome/common/net/url_fetcher.h"
-#include "gfx/rect.h"
-#include "googleurl/src/gurl.h"
-#include "views/controls/button/radio_button.h"
-#include "views/controls/combobox/combobox.h"
-#include "views/controls/textfield/textfield.h"
-#include "views/controls/link.h"
-#include "views/controls/image_view.h"
-#include "views/view.h"
-#include "views/window/dialog_delegate.h"
-
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/syslogs_library.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
-#endif
-
-namespace views {
-class Checkbox;
-class Label;
-class Throbber;
-class Window;
-class RadioButton;
-class Link;
-}
-
-class Profile;
-class TabContents;
-class BugReportComboBoxModel;
-
-// BugReportView draws the dialog that allows the user to report a
-// bug in rendering a particular page (note: this is not a crash
-// report, which are handled separately by Breakpad). It packages
-// up the URL, a text description, system information and optionally
-// a screenshot; then it submits the info through https to the google
-// feedback chrome end-point.
-//
-// Note: This UI is being used for the Chrome OS dogfood release only
-// In the very next iteration, this will be replaced by a HTML
-// based UI, which will be common for all platforms
-class BugReportView : public views::View,
- public views::DialogDelegate,
- public views::Combobox::Listener,
-#if defined(OS_CHROMEOS)
- public views::LinkController,
-#endif
- public views::Textfield::Controller {
- public:
- BugReportView(Profile* profile, TabContents* tab);
- virtual ~BugReportView();
-
- // NOTE: set_captured_image takes ownership of the vector
- void set_captured_image(std::vector<unsigned char>* png_data) {
- captured_image_.reset(png_data);
- }
-
- void set_screen_size(const gfx::Rect& screen_size) {
- screen_size_ = screen_size;
- }
-
- // Set all additional reporting controls to disabled
- // if phishing report
- void UpdateReportingControls(bool is_phishing_report);
-
- // Overridden from views::View:
- virtual gfx::Size GetPreferredSize();
-
- // views::Textfield::Controller implementation:
- virtual void ContentsChanged(views::Textfield* sender,
- const string16& new_contents);
- virtual bool HandleKeystroke(views::Textfield* sender,
- const views::Textfield::Keystroke& key);
-
- // views::Combobox::Listener implementation:
- virtual void ItemChanged(views::Combobox* combobox, int prev_index,
- int new_index);
-
-#if defined(OS_CHROMEOS)
- // Overridden from views::LinkController:
- virtual void LinkActivated(views::Link* source, int event_flags);
-
- // Disable the include last image radio control
- void DisableLastImageRadio() {
- include_last_screen_image_radio_->SetEnabled(false);
- }
-
- // NOTE: set_last_image takes ownership of the vector
- void set_last_image(std::vector<unsigned char>* png_data) {
- last_image_.reset(png_data);
- }
-#endif
-
- // Overridden from views::DialogDelegate:
- virtual std::wstring GetDialogButtonLabel(
- MessageBoxFlags::DialogButton button) const;
- virtual int GetDefaultDialogButton() const;
- virtual bool CanResize() const;
- virtual bool CanMaximize() const;
- virtual bool IsAlwaysOnTop() const;
- virtual bool HasAlwaysOnTopMenu() const;
- virtual bool IsModal() const;
- virtual std::wstring GetWindowTitle() const;
- virtual bool Accept();
- virtual views::View* GetContentsView();
-
- private:
- class PostCleanup;
-
- // Set OS Version information in a string (maj.minor.build SP)
- void SetOSVersion(std::string *os_version);
-
- // Initializes the controls on the dialog.
- void SetupControl();
- // helper function to create a MIME part boundary string
- void CreateMimeBoundary(std::string *out);
- // Sends the data via an HTTP POST
- void SendReport();
-
- // Redirects the user to Google's phishing reporting page.
- void ReportPhishing();
-
- views::Label* bug_type_label_;
- views::Combobox* bug_type_combo_;
- views::Label* page_title_label_;
- views::Label* page_title_text_;
- views::Label* page_url_label_;
- views::Textfield* page_url_text_;
- views::Label* description_label_;
- views::Textfield* description_text_;
- views::Checkbox* include_page_source_checkbox_;
-#if defined(OS_CHROMEOS)
- views::Label* user_email_label_;
- views::Textfield* user_email_text_;
- views::RadioButton* include_new_screen_image_radio_;
- views::RadioButton* include_last_screen_image_radio_;
- views::RadioButton* include_no_screen_image_radio_;
- views::Link* system_information_url_control_;
-
- scoped_ptr<chromeos::LogDictionaryType> sys_info_;
- scoped_ptr< std::vector<unsigned char> > last_image_;
-#endif
- views::Checkbox* include_page_image_checkbox_;
-
-
- scoped_ptr<BugReportComboBoxModel> bug_type_model_;
-
- Profile* profile_;
-
- std::wstring version_;
- gfx::Rect screen_size_;
- scoped_ptr< std::vector<unsigned char> > captured_image_;
-
- TabContents* tab_;
-
- // Used to distinguish the report type: Phishing or other.
- int problem_type_;
-
- // Save the description the user types in when we clear the dialog for the
- // phishing option. If the user changes the report type back, we reinstate
- // their original text so they don't have to type it again.
- std::wstring old_report_text_;
-
- DISALLOW_COPY_AND_ASSIGN(BugReportView);
-};
-
-#endif // CHROME_BROWSER_VIEWS_BUG_REPORT_VIEW_H_
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 75c73ed..1e32b5c 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -20,10 +20,12 @@
#include "chrome/browser/autocomplete/autocomplete_popup_view.h"
#include "chrome/browser/automation/ui_controls.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/debugger/devtools_window.h"
+#include "chrome/browser/dom_ui/bug_report_ui.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/ntp_background_util.h"
#include "chrome/browser/page_info_window.h"
@@ -54,6 +56,7 @@
#include "chrome/common/native_window_notification_source.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
#include "gfx/canvas_skia.h"
#include "grit/app_resources.h"
#include "grit/chromium_strings.h"
@@ -1115,11 +1118,7 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
}
void BrowserView::ShowReportBugDialog() {
- // Retrieve the URL for the current tab (if any) and tell the BugReportView
- TabContents* current_tab = browser_->GetSelectedTabContents();
- if (!current_tab)
- return;
- browser::ShowBugReportView(GetWindow(), browser_->profile(), current_tab);
+ browser::ShowHtmlBugReportView(GetWindow(), browser_.get());
}
void BrowserView::ShowClearBrowsingDataDialog() {
diff --git a/chrome/browser/wrench_menu_model.cc b/chrome/browser/wrench_menu_model.cc
index 8dd51e4..ffd1d17 100644
--- a/chrome/browser/wrench_menu_model.cc
+++ b/chrome/browser/wrench_menu_model.cc
@@ -147,6 +147,8 @@ void ToolsMenuModel::Build(Browser* browser) {
AddItemWithStringId(IDC_CLEAR_BROWSING_DATA, IDS_CLEAR_BROWSING_DATA);
AddSeparator();
+ AddItemWithStringId(IDC_REPORT_BUG, IDS_REPORT_BUG);
+ AddSeparator();
encoding_menu_model_.reset(new EncodingMenuModel(browser));
AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU,
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 1d09ef9..59468ab 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -327,8 +327,8 @@
'browser/bug_report_util.h',
# TODO(rkc): Find a better way to include these files
'<(protoc_out_dir)/chrome/browser/userfeedback/proto/annotations.pb.cc',
+ '<(protoc_out_dir)/chrome/browser/userfeedback/proto/chrome.pb.cc',
'<(protoc_out_dir)/chrome/browser/userfeedback/proto/common.pb.cc',
- '<(protoc_out_dir)/chrome/browser/userfeedback/proto/config.pb.cc',
'<(protoc_out_dir)/chrome/browser/userfeedback/proto/dom.pb.cc',
'<(protoc_out_dir)/chrome/browser/userfeedback/proto/extension.pb.cc',
'<(protoc_out_dir)/chrome/browser/userfeedback/proto/math.pb.cc',
@@ -1140,6 +1140,8 @@
'browser/dom_ui/autofill_options_handler.h',
'browser/dom_ui/bookmarks_ui.cc',
'browser/dom_ui/bookmarks_ui.h',
+ 'browser/dom_ui/bug_report_ui.cc',
+ 'browser/dom_ui/bug_report_ui.h',
'browser/dom_ui/chrome_url_data_manager.cc',
'browser/dom_ui/chrome_url_data_manager.h',
'browser/dom_ui/about_page_handler.cc',
@@ -1184,6 +1186,8 @@
'browser/dom_ui/dom_ui_factory.h',
'browser/dom_ui/dom_ui_favicon_source.cc',
'browser/dom_ui/dom_ui_favicon_source.h',
+ 'browser/dom_ui/dom_ui_screenshot_source.cc',
+ 'browser/dom_ui/dom_ui_screenshot_source.h',
'browser/dom_ui/dom_ui_theme_source.cc',
'browser/dom_ui/dom_ui_theme_source.h',
'browser/dom_ui/dom_ui_thumbnail_source.cc',
@@ -2674,8 +2678,6 @@
'browser/views/browser_dialogs.h',
'browser/views/bubble_border.cc',
'browser/views/bubble_border.h',
- 'browser/views/bug_report_view.cc',
- 'browser/views/bug_report_view.h',
'browser/views/certificate_viewer_win.cc',
'browser/views/chrome_views_delegate.cc',
'browser/views/chrome_views_delegate.h',
@@ -3395,8 +3397,6 @@
['include', '^browser/views/browser_bubble.h'],
['include', '^browser/views/bubble_border.cc'],
['include', '^browser/views/bubble_border.h'],
- ['include', '^browser/views/bug_report_view.cc'],
- ['include', '^browser/views/bug_report_view.h'],
['include', '^browser/views/chrome_views_delegate.cc'],
['include', '^browser/views/clear_browsing_data.cc'],
['include', '^browser/views/clear_browsing_data.h'],
@@ -3801,8 +3801,8 @@
'type': 'none',
'sources': [
'browser/userfeedback/proto/annotations.proto',
+ 'browser/userfeedback/proto/chrome.proto',
'browser/userfeedback/proto/common.proto',
- 'browser/userfeedback/proto/config.proto',
'browser/userfeedback/proto/dom.proto',
'browser/userfeedback/proto/extension.proto',
'browser/userfeedback/proto/math.proto',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index bc00a4ef..562e7af4 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -517,6 +517,9 @@ const char kExtensionProcess[] = "extension";
// Frequency in seconds for Extensions auto-update.
const char kExtensionsUpdateFrequency[] = "extensions-update-frequency";
+// Alternative feedback server to use when submitting user feedback
+const char kFeedbackServer[] = "feedback-server";
+
// The file descriptor limit is set to the value of this switch, subject to the
// OS hard limits. Useful for testing that file descriptor exhaustion is handled
// gracefully.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 6f0ce67..8b16067 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -163,6 +163,7 @@ extern const char kExperimentalSpellcheckerFeatures[];
extern const char kExplicitlyAllowedPorts[];
extern const char kExtensionProcess[];
extern const char kExtensionsUpdateFrequency[];
+extern const char kFeedbackServer[];
extern const char kFileDescriptorLimit[];
extern const char kFirstRun[];
extern const char kForceFieldTestNameAndValue[];
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 5578981..14c1ea3 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -65,6 +65,7 @@ const char kAboutBrowserCrash[] = "about:inducebrowsercrashforrealz";
const char kChromeUIAboutURL[] = "chrome://options/about";
const char kChromeUIAppLauncherURL[] = "chrome://newtab/#mode=app-launcher";
const char kChromeUIBookmarksURL[] = "chrome://bookmarks/";
+const char kChromeUIBugReportURL[] = "chrome://bugreport/";
const char kChromeUIDevToolsURL[] = "chrome://devtools/";
const char kChromeUIDownloadsURL[] = "chrome://downloads/";
const char kChromeUIExtensionsURL[] = "chrome://extensions/";
@@ -82,6 +83,7 @@ const char kChromeUIRegisterPageURL[] = "chrome://register/";
const char kChromeUISlideshowURL[] = "chrome://slideshow/";
const char kChromeUIBookmarksHost[] = "bookmarks";
+const char kChromeUIBugReportHost[] = "bugreport";
const char kChromeUIDevToolsHost[] = "devtools";
const char kChromeUIDialogHost[] = "dialog";
const char kChromeUIDownloadsHost[] = "downloads";
@@ -104,6 +106,7 @@ const char kChromeUISlideshowHost[] = "slideshow";
const char kChromeUISyncResourcesHost[] = "syncresources";
const char kChromeUIRemotingResourcesHost[] = "remotingresources";
const char kChromeUIThemePath[] = "theme";
+const char kChromeUIScreenshotPath[] = "screenshots";
const char kChromeUIThumbnailPath[] = "thumb";
const char kAppCacheViewInternalsURL[] = "chrome://appcache-internals/";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 5834b13..fbaa16d 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -58,6 +58,7 @@ extern const char kAboutVersionURL[];
extern const char kChromeUIAboutURL[];
extern const char kChromeUIAppLauncherURL[];
extern const char kChromeUIBookmarksURL[];
+extern const char kChromeUIBugReportURL[];
extern const char kChromeUIDevToolsURL[];
extern const char kChromeUIDownloadsURL[];
extern const char kChromeUIExtensionsURL[];
@@ -77,6 +78,7 @@ extern const char kChromeUISlideshowURL[];
// chrome components of URLs. Should be kept in sync with the full URLs
// above.
extern const char kChromeUIBookmarksHost[];
+extern const char kChromeUIBugReportHost[];
extern const char kChromeUIDevToolsHost[];
extern const char kChromeUIDialogHost[];
extern const char kChromeUIDownloadsHost[];
@@ -95,6 +97,7 @@ extern const char kChromeUIPrintHost[];
extern const char kChromeUIRegisterPageHost[];
extern const char kChromeUIRemotingHost[];
extern const char kChromeUIResourcesHost[];
+extern const char kChromeUIScreenshotPath[];
extern const char kChromeUISlideshowHost[];
extern const char kChromeUISyncResourcesHost[];
extern const char kChromeUIRemotingResourcesHost[];