summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/x11_util.cc2
-rw-r--r--base/mac_util.h3
-rw-r--r--base/mac_util.mm5
-rw-r--r--base/mac_util_unittest.mm4
-rw-r--r--chrome/app/generated_resources.grd17
-rw-r--r--chrome/browser/browser.cc5
-rw-r--r--chrome/browser/bug_report_util.cc174
-rw-r--r--chrome/browser/bug_report_util.h23
-rw-r--r--chrome/browser/cocoa/bug_report_window_controller.h3
-rw-r--r--chrome/browser/cocoa/bug_report_window_controller.mm8
-rw-r--r--chrome/browser/userfeedback/proto/annotations.proto26
-rw-r--r--chrome/browser/userfeedback/proto/common.proto22
-rw-r--r--chrome/browser/userfeedback/proto/config.proto139
-rw-r--r--chrome/browser/userfeedback/proto/dom.proto98
-rw-r--r--chrome/browser/userfeedback/proto/extension.proto99
-rw-r--r--chrome/browser/userfeedback/proto/math.proto22
-rw-r--r--chrome/browser/userfeedback/proto/web.proto70
-rw-r--r--chrome/browser/views/bug_report_view.cc103
-rw-r--r--chrome/browser/views/bug_report_view.h30
-rw-r--r--chrome/chrome_browser.gypi65
-rw-r--r--third_party/protobuf2/protobuf.gyp2
21 files changed, 799 insertions, 121 deletions
diff --git a/app/x11_util.cc b/app/x11_util.cc
index edf5f2f..78e09fc 100644
--- a/app/x11_util.cc
+++ b/app/x11_util.cc
@@ -736,7 +736,7 @@ void GrabWindowSnapshot(GtkWindow* gtk_window,
Display* display = GDK_WINDOW_XDISPLAY(gdk_window);
XID win = GDK_WINDOW_XID(gdk_window);
XWindowAttributes attr;
- if (XGetWindowAttributes(display, win, &attr) != 0) {
+ if (XGetWindowAttributes(display, win, &attr) == 0) {
LOG(ERROR) << "Couldn't get window attributes";
return;
}
diff --git a/base/mac_util.h b/base/mac_util.h
index 2c59a87..bfe2079 100644
--- a/base/mac_util.h
+++ b/base/mac_util.h
@@ -118,7 +118,8 @@ void ActivateProcess(pid_t);
// Pulls a snapshot of the entire browser into png_representation.
void GrabWindowSnapshot(NSWindow* window,
- std::vector<unsigned char>* png_representation);
+ std::vector<unsigned char>* png_representation,
+ int* width, int* height);
// Takes a path to an (executable) binary and tries to provide the path to an
// application bundle containing it. It takes the outermost bundle that it can
diff --git a/base/mac_util.mm b/base/mac_util.mm
index 00ef9e09..cd7a949 100644
--- a/base/mac_util.mm
+++ b/base/mac_util.mm
@@ -244,7 +244,8 @@ bool ShouldWindowsMiniaturizeOnDoubleClick() {
}
void GrabWindowSnapshot(NSWindow* window,
- std::vector<unsigned char>* png_representation) {
+ std::vector<unsigned char>* png_representation,
+ int* width, int* height) {
// Make sure to grab the "window frame" view so we get current tab +
// tabstrip.
NSView* view = [[window contentView] superview];
@@ -255,6 +256,8 @@ void GrabWindowSnapshot(NSWindow* window,
const unsigned char* buf = static_cast<const unsigned char*>([data bytes]);
NSUInteger length = [data length];
if (buf != NULL && length > 0){
+ *width = static_cast<int>([rep pixelsWide]);
+ *height = static_cast<int>([rep pixelsHigh]);
png_representation->assign(buf, buf + length);
DCHECK(png_representation->size() > 0);
}
diff --git a/base/mac_util_unittest.mm b/base/mac_util_unittest.mm
index b77472b..aebb731 100644
--- a/base/mac_util_unittest.mm
+++ b/base/mac_util_unittest.mm
@@ -66,7 +66,9 @@ TEST_F(MacUtilTest, TestGrabWindowSnapshot) {
scoped_ptr<std::vector<unsigned char> > png_representation(
new std::vector<unsigned char>);
- GrabWindowSnapshot(window, png_representation.get());
+ int width, height;
+ GrabWindowSnapshot(window, png_representation.get(),
+ &width, &height);
// Copy png back into NSData object so we can make sure we grabbed a png.
scoped_nsobject<NSData> image_data(
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a465f19..7430470 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4102,6 +4102,23 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_BUGREPORT_DESCRIPTION_LABEL" desc="Label for description field">
Description:
</message>
+ <if expr="pp_ifdef('chromeos')">
+ <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 screen shot
+ </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 a new 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
+ </message>
+ <message name="IDS_BUGREPORT_SYSTEM_INFORMATION_URL" desc="URL for system information on the bug report dialog box">
+ file:///etc/logs/last
+ </message>
+ <message name="IDS_BUGREPORT_SYSTEM_INFORMATION_URL_TEXT" desc="Text for system information url on the bug report dialog box">
+ System Information
+ </message>
+ </if>
<message name="IDS_BUGREPORT_INCLUDE_PAGE_SOURCE_CHKBOX" desc="Checkbox for including page source">
Send source of current page
</message>
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index f375ce0..492ebfb 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1609,10 +1609,15 @@ void Browser::OpenNewProfileDialog() {
}
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/bug_report_util.cc b/chrome/browser/bug_report_util.cc
index b23943e..37aa8f8 100644
--- a/chrome/browser/bug_report_util.cc
+++ b/chrome/browser/bug_report_util.cc
@@ -17,6 +17,8 @@
#include "grit/locale_settings.h"
#include "unicode/locid.h"
+#include <string>
+
namespace {
const int kBugReportVersion = 1;
@@ -26,7 +28,17 @@ const char kReportPhishingUrl[] =
// URL to post bug reports to.
const char* const kBugReportPostUrl =
- "http://web-bug.appspot.com/bugreport";
+ "http://feedback2-dev.corp.google.com/tools/feedback/chrome/__submit";
+
+const char* const kProtBufMimeType = "application/x-protobuf";
+const char* const kPngMimeType = "image/png";
+
+// Tags we use in product specific data
+const char* const kPageTitleTag = "PAGE TITLE";
+const char* const kProblemTypeTag = "PROBLEM TYPE";
+const char* const kChromeVersionTag = "CHROME VERSION";
+const char* const kOsVersionTag = "OS VERSION";
+
} // namespace
@@ -89,60 +101,59 @@ void BugReportUtil::SetOSVersion(std::string *os_version) {
#endif
}
-// Create a MIME boundary marker (27 '-' characters followed by 16 hex digits).
-void BugReportUtil::CreateMimeBoundary(std::string *out) {
- int r1 = rand();
- int r2 = rand();
- SStringPrintf(out, "---------------------------%08X%08X", r1, r2);
+// static
+void BugReportUtil::AddFeedbackData(
+ userfeedback::ExternalExtensionSubmit* feedback_data,
+ const std::string& key, const std::string& value) {
+ // Create log_value object and add it to the web_data object
+ userfeedback::ProductSpecificData log_value;
+ log_value.set_key(key);
+ log_value.set_value(value);
+ userfeedback::WebData* web_data = feedback_data->mutable_web_data();
+ *(web_data->add_product_specific_data()) = log_value;
}
// static
void BugReportUtil::SendReport(Profile* profile,
- std::string page_title_text,
+ const std::string& page_title_text,
int problem_type,
- std::string page_url_text,
- std::string description,
+ const std::string& page_url_text,
+ const std::string& description,
const char* png_data,
- int png_data_length) {
+ int png_data_length,
+ int png_width,
+ int png_height) {
GURL post_url(kBugReportPostUrl);
- std::string mime_boundary;
- CreateMimeBoundary(&mime_boundary);
- // Create a request body and add the mandatory parameters.
- std::string post_body;
+ // Create google feedback protocol buffer objects
+ userfeedback::ExternalExtensionSubmit feedback_data;
+ // type id set to 0, unused field but needs to be initialized to 0
+ feedback_data.set_type_id(0);
+
+ userfeedback::CommonData* common_data = feedback_data.mutable_common_data();
+ userfeedback::WebData* web_data = feedback_data.mutable_web_data();
- // Add the protocol version:
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"data_version\"\r\n\r\n");
- post_body.append(StringPrintf("%d\r\n", kBugReportVersion));
+ // set GAIA id to 0 to indicate no username available
+ common_data->set_gaia_id(0);
// Add the page title.
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append(page_title_text + "\r\n");
-
- // Add the problem type.
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"problem\"\r\n\r\n");
- post_body.append(StringPrintf("%d\r\n", problem_type));
-
- // Add in the URL, if we have one.
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"url\"\r\n\r\n");
-
- // Convert URL to UTF8.
- if (page_url_text.empty())
- post_body.append("n/a\r\n");
- else
- post_body.append(page_url_text + "\r\n");
-
- // Add Chrome version.
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"chrome_version\"\r\n\r\n");
+ AddFeedbackData(&feedback_data, std::string(kPageTitleTag),
+ page_title_text);
+ AddFeedbackData(&feedback_data, std::string(kProblemTypeTag),
+ StringPrintf("%d\r\n", problem_type));
+
+ // 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);
+
+ // Set the url
+ web_data->set_url(page_url_text);
+
+ // Add the Chrome version
std::string chrome_version;
scoped_ptr<FileVersionInfo> version_info(
chrome_app::GetChromeVersionInfo());
@@ -152,79 +163,45 @@ void BugReportUtil::SendReport(Profile* profile,
" (" + WideToUTF8(version_info->last_change()) + ")";
}
- if (chrome_version.empty())
- post_body.append("n/a\r\n");
- else
- post_body.append(chrome_version + "\r\n");
+ if (!chrome_version.empty())
+ AddFeedbackData(&feedback_data, std::string(kChromeVersionTag),
+ chrome_version);
// Add OS version (eg, for WinXP SP2: "5.1.2600 Service Pack 2").
std::string os_version = "";
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"os_version\"\r\n\r\n");
SetOSVersion(&os_version);
- post_body.append(os_version + "\r\n");
+ AddFeedbackData(&feedback_data, std::string(kOsVersionTag), os_version);
- // Add locale.
-#if defined(OS_MACOSX)
- std::string chrome_locale = g_browser_process->GetApplicationLocale();
-#else
- icu::Locale locale = icu::Locale::getDefault();
- const char *lang = locale.getLanguage();
- std::string chrome_locale = (lang)? lang:"en";
-#endif
-
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"chrome_locale\"\r\n\r\n");
- post_body.append(chrome_locale + "\r\n");
-
- // Add a description if we have one.
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; "
- "name=\"description\"\r\n\r\n");
-
- if (description.empty())
- post_body.append("n/a\r\n");
- else
- post_body.append(description + "\r\n");
// Include the page image if we have one.
- if (png_data != NULL && png_data_length > 0) {
- post_body.append("--" + mime_boundary + "\r\n");
- post_body.append("Content-Disposition: form-data; name=\"screenshot\"; "
- "filename=\"screenshot.png\"\r\n");
- post_body.append("Content-Type: application/octet-stream\r\n");
- post_body.append(StringPrintf("Content-Length: %d\r\n\r\n",
- png_data_length));
- post_body.append(png_data, png_data_length);
- post_body.append("\r\n");
+ if (png_data) {
+ userfeedback::PostedScreenshot screenshot;
+ screenshot.set_mime_type(kPngMimeType);
+
+ // Set the dimensions of the screenshot
+ userfeedback::Dimensions dimensions;
+ dimensions.set_width(static_cast<float>(png_width));
+ dimensions.set_height(static_cast<float>(png_height));
+ *(screenshot.mutable_dimensions()) = dimensions;
+ screenshot.set_binary_content(std::string(png_data, png_data_length));
+
+ // Set the screenshot object in feedback
+ *(feedback_data.mutable_screenshot()) = screenshot;
}
// TODO(awalker): include the page source if we can get it.
// if (include_page_source_checkbox_->checked()) {
// }
- // Terminate the body.
- post_body.append("--" + mime_boundary + "--\r\n");
-
// 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);
fetcher->set_request_context(profile->GetRequestContext());
- std::string mime_type("multipart/form-data; boundary=");
- mime_type += mime_boundary;
- fetcher->set_upload_data(mime_type, post_body);
- fetcher->Start();
-}
-// static
-std::string BugReportUtil::GetMimeType() {
- std::string mime_type("multipart/form-data; boundary=");
- std::string mime_boundary;
- CreateMimeBoundary(&mime_boundary);
- mime_type += mime_boundary;
- return mime_type;
+ std::string post_body;
+ feedback_data.SerializeToString(&post_body);
+ fetcher->set_upload_data(std::string(kProtBufMimeType), post_body);
+ fetcher->Start();
}
// static
@@ -236,4 +213,3 @@ void BugReportUtil::ReportPhishing(TabContents* currentTab,
GURL(),
PageTransition::LINK);
}
-
diff --git a/chrome/browser/bug_report_util.h b/chrome/browser/bug_report_util.h
index aef1760..a56d4e1 100644
--- a/chrome/browser/bug_report_util.h
+++ b/chrome/browser/bug_report_util.h
@@ -15,6 +15,11 @@
#endif
#include "base/scoped_ptr.h"
+#include "chrome/browser/userfeedback/proto/common.pb.h"
+#include "chrome/browser/userfeedback/proto/extension.pb.h"
+#include "chrome/browser/userfeedback/proto/math.pb.h"
+#include "gfx/rect.h"
+
class Profile;
class TabContents;
@@ -44,26 +49,28 @@ class BugReportUtil {
// Generates bug report data.
static void SendReport(Profile* profile,
- std::string page_title_text,
+ const std::string& page_title_text,
int problem_type,
- std::string page_url_text,
- std::string description,
+ const std::string& page_url_text,
+ const std::string& description,
const char* png_data,
- int png_data_length);
+ int png_data_length,
+ int png_width,
+ int png_height);
// Redirects the user to Google's phishing reporting page.
static void ReportPhishing(TabContents* currentTab,
const std::string& phishing_url);
- static std::string GetMimeType();
-
class PostCleanup;
private:
- static void CreateMimeBoundary(std::string *out);
+ // Add a key value pair to the feedback object
+ static void AddFeedbackData(
+ userfeedback::ExternalExtensionSubmit* feedback_data,
+ const std::string& key, const std::string& value);
DISALLOW_IMPLICIT_CONSTRUCTORS(BugReportUtil);
};
#endif // CHROME_BROWSER_BUG_REPORT_UTIL_H_
-
diff --git a/chrome/browser/cocoa/bug_report_window_controller.h b/chrome/browser/cocoa/bug_report_window_controller.h
index 6c79080..88a7ca6 100644
--- a/chrome/browser/cocoa/bug_report_window_controller.h
+++ b/chrome/browser/cocoa/bug_report_window_controller.h
@@ -25,6 +25,9 @@ class TabContents;
// Holds screenshot of current tab.
std::vector<unsigned char> pngData_;
+ // Width and height of the current tab's screenshot.
+ int pngWidth_;
+ int pngHeight_;
// Values bound to data in the dialog box. These values cannot be boxed in
// scoped_nsobjects because we use them for bindings.
diff --git a/chrome/browser/cocoa/bug_report_window_controller.mm b/chrome/browser/cocoa/bug_report_window_controller.mm
index 650f8b3..df29f99 100644
--- a/chrome/browser/cocoa/bug_report_window_controller.mm
+++ b/chrome/browser/cocoa/bug_report_window_controller.mm
@@ -63,13 +63,17 @@
currentTab_->controller().GetActiveEntry()->url().spec())];
[self setPageTitle:base::SysUTF16ToNSString(currentTab_->GetTitle())];
mac_util::GrabWindowSnapshot(
- currentTab_->view()->GetTopLevelNativeWindow(), &pngData_);
+ currentTab_->view()->GetTopLevelNativeWindow(), &pngData_,
+ &pngWidth_, &pngHeight_);
} else {
// If no current tab exists, create a menu without the "broken page"
// options, with page URL and title empty, and screenshot disabled.
[self setSendScreenshot:NO];
[self setDisableScreenshotCheckbox:YES];
}
+
+ pngHeight_ = 0;
+ pngWidth_ = 0;
}
return self;
}
@@ -112,7 +116,7 @@
base::SysNSStringToUTF8(bugDescription_),
sendScreenshot_ && !pngData_.empty() ?
reinterpret_cast<const char *>(&(pngData_[0])) : NULL,
- pngData_.size());
+ pngData_.size(), pngWidth_, pngHeight_);
}
[self closeDialog];
}
diff --git a/chrome/browser/userfeedback/proto/annotations.proto b/chrome/browser/userfeedback/proto/annotations.proto
new file mode 100644
index 0000000..b99aa04
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/annotations.proto
@@ -0,0 +1,26 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: micapolos@google.com (Michal Pociecha-Los)
+//
+// Messages containing data about the annotations drawn on the screenshot of a
+// web page.
+
+syntax = "proto2";
+
+package userfeedback;
+
+import "math.proto";
+import "dom.proto";
+
+// An annotation drawn by the user on the screenshot of a web page.
+message Annotation {
+ // A rectangular area covered by this annotation on annotated image.
+ // The (0, 0) coordinate is placed in the top-left corner of the image.
+ // One unit corresponds to one pixel.
+ required Rectangle rectangle = 1;
+
+ // A snippet of text displayed inside annotated portion of a web page.
+ optional string snippet = 2;
+
+ // A path from root element of the document to the annotated element.
+ optional HtmlPath annotatedElementPath = 3;
+};
diff --git a/chrome/browser/userfeedback/proto/common.proto b/chrome/browser/userfeedback/proto/common.proto
new file mode 100644
index 0000000..97c60fb
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/common.proto
@@ -0,0 +1,22 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: morgwai@google.com (Morgwai Kotarbinski)
+//
+// Basic messages used by all systems (extension, feedbackserver,
+// silver-bullet clustering, android etc).
+
+syntax = "proto2";
+
+package userfeedback;
+
+// Data present in all kinds of feedbacks, regardless of source (Web, Android,
+// other).
+message CommonData {
+ optional fixed64 gaia_id = 1;
+
+ // 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 user_email = 3;
+};
diff --git a/chrome/browser/userfeedback/proto/config.proto b/chrome/browser/userfeedback/proto/config.proto
new file mode 100644
index 0000000..f36c482
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/config.proto
@@ -0,0 +1,139 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: morgwai@google.com (Morgwai Kotarbinski)
+//
+// Messages containing configuration of Feedback Service
+// that control classification and processing of submitted feedbacks.
+
+syntax = "proto2";
+
+package userfeedback;
+
+// Product for which feedback can be sent: GMail, Writely etc.
+message Product {
+ required int32 id = 1;
+
+ required string name = 2;
+
+ repeated string owner = 3;
+};
+
+// Contains information needed to check whether particular
+// feedback type applies to the page user is browsing and forward
+// it's execution to a specific handler. It also carries information
+// about the creator.
+// TODO(morgwai): design new structure of Type with fields relevant
+// for android, web, selenium grouped into submessages.
+message FeedbackTypeData {
+ // index of feedback type as found in database
+ required int32 id = 1;
+
+ // Specifies whether this feedback type is currently enabled and
+ // feedback of this type can be submitted.
+ required bool enabled = 2;
+
+ // Problem name of this feedback type on Google Feedback pages.
+ required string problem_name = 3;
+
+ // Name of the product to which this feedback type belongs.
+ optional string product_name = 4;
+
+ // Tag 5 is used by some legacy data that is already in production db.
+
+ // matcher to execute against page
+ required MatcherData matcher = 6;
+
+ // Comma separated list of email addresses to which email notification
+ // is sent upon each new feedback of this type.
+ // No email is sent if this field is set to an empty string.
+ required string notification_email = 7;
+
+ // Do not use tag 8, 9, 10. They were used by a legacy field.
+
+ // Encapsulates different kind of feedback type.
+ enum Kind {
+ // Product feedback type.
+ PRODUCT = 1;
+ // Special feedback type (e.g. fixit).
+ SPECIAL = 2;
+ }
+
+ // Kind of feedback type.
+ optional Kind kind = 11 [default=PRODUCT];
+
+ // Prefix to be added to summary of notification email sent for feedback of this
+ // type.
+ optional string summary_prefix = 12;
+
+ // String template with which "Additional Info" field in extension
+ // should be initially filled.
+ optional string template = 13;
+
+ // ID of the product this feedback type belongs to.
+ optional int32 product_id = 14;
+
+ // Tag that is used for marking feedback types that require non-ordinary handling.
+ // E.g: This field is equal:
+ // "unclassified" for Unclassified feedback,
+ // "android" for android feedback
+ // "selenium" for selenium feedback
+ optional string tag = 15;
+
+ // Problem description visible in feedback extension.
+ optional string problem_description = 16;
+
+ // Visibilities of feedback type.
+ enum Visibility {
+ // feedback type visible in external extension only
+ EXTERNAL = 1;
+ // feedback type visible in internal extension only
+ INTERNAL = 2;
+ }
+
+ // Specifies the visibility of this feedback type.
+ optional Visibility visibility = 17 [default=INTERNAL];
+
+ // tag 18 was used by removed field
+
+ // Specifies Buganizer fields
+ // TODO(kaczmarek): enable once we migrated to new protos.
+ // optional BuganizerSettings buganizer_settings = 19;
+
+ // Channel via which notification about feedback should be send
+ enum NotifyChannel {
+ // Send email notification.
+ EMAIL = 1;
+ // File a bug in buganizer.
+ BUGANIZER = 2;
+ // File a bug in issue tracker.
+ ISSUE_TRACKER = 3;
+ }
+
+ // Specifies channel via which notification about feedback of this type should be sent.
+ optional NotifyChannel notify_channel = 20 [default=EMAIL];
+
+ // Granularity of notifications.
+ enum NotificationGranularity {
+ // Send notification per each feedback.
+ FEEDBACK = 1;
+ // Send notification per clustered group of similar feedbacks.
+ CLUSTER = 2;
+ }
+
+ // Specifies granularity of notifications send for feedbacks of this type.
+ optional NotificationGranularity notification_granularity = 21 [default=FEEDBACK];
+
+ // Threshold for number of feedbacks in a cluster at which notification is sent.
+ optional int32 clustering_threshold = 22 [default=5];
+};
+
+// Used to detect content relevant to particular type of feedback.
+message MatcherData {
+ // XPATH expression to match against page.
+ required string content_matcher = 1;
+
+ // Regexp matching page URL.
+ required string url_matcher = 2;
+
+ // Approval by feedback admins
+ optional bool url_matcher_approved = 3 [default=true];
+};
diff --git a/chrome/browser/userfeedback/proto/dom.proto b/chrome/browser/userfeedback/proto/dom.proto
new file mode 100644
index 0000000..23958ac
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/dom.proto
@@ -0,0 +1,98 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: micapolos@google.com (Michal Pociecha-Los)
+//
+// Messages containing DOM data captured from the browser.
+// It includes the structure of the HTML document and Navigator data.
+
+syntax = "proto2";
+
+package userfeedback;
+
+// Data captured from HTMLDocument DOM object.
+message HtmlDocument {
+
+ // The value of document.URL property.
+ required string url = 1;
+
+ // The value of document.title property.
+ optional string title = 2;
+
+ // The value of document.documentElement property.
+ optional HtmlElement document_element = 3;
+};
+
+// Data captured from HTMLElement DOM object.
+message HtmlElement {
+
+ // The value of element.tagName property.
+ required string tag_name = 1;
+
+ // The value of element.id property.
+ optional string id = 2;
+
+ // The value of element.className property.
+ optional string class_name = 3;
+
+ // A list of child elements.
+ repeated HtmlElement child_element = 4;
+
+ // The value of frame.contentDocument property for FRAME and IFRAME elements.
+ optional HtmlDocument frame_content_document = 5;
+};
+
+// Data captured from DOM Navigator object.
+message Navigator {
+
+ // The value of 'navigator.appCodeName' property.
+ optional string app_code_name = 1;
+
+ // The value of 'navigator.appName' property.
+ optional string app_name = 2;
+
+ // The value of 'navigator.appVersion' property.
+ optional string app_version = 3;
+
+ // The value of 'navigator.appMinorVersion' property.
+ optional string app_minor_version = 4;
+
+ // The value of 'navigator.cookieEnabled' property.
+ optional bool cookie_enabled = 5;
+
+ // The value of 'navigator.cpuClass' property.
+ optional string cpu_class = 6;
+
+ // The value of 'navigator.onLine' property.
+ optional bool on_line = 7;
+
+ // The value of 'navigator.platform' property.
+ optional string platform = 8;
+
+ // The value of 'navigator.browserLanguage' property.
+ optional string browser_language = 9;
+
+ // The value of 'navigator.systemLanguage' property.
+ optional string system_language = 10;
+
+ // The value of 'navigator.userAgent' property.
+ optional string user_agent = 11;
+
+ // The return value of 'navigator.javaEnabled()' method.
+ optional bool java_enabled = 12;
+
+ // The return value of 'navigator.taintEnabled()' method.
+ optional bool taint_enabled = 13;
+
+ // Plugin names specified by 'navigator.plugins' property.
+ repeated string plugin_name = 14;
+};
+
+// A path in the HTML document between two elements, which are in the
+// ancestor-descendant relationship.
+message HtmlPath {
+
+ // Ordered list of zero-based indices.
+ // Empty path selects root element.
+ // Non-negative index N selects (N+1)-th child.
+ // Index -1 selects root element from frame content document.
+ repeated int32 index = 1;
+};
diff --git a/chrome/browser/userfeedback/proto/extension.proto b/chrome/browser/userfeedback/proto/extension.proto
new file mode 100644
index 0000000..d600f8a
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/extension.proto
@@ -0,0 +1,99 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: morgwai@google.com (Morgwai Kotarbinski)
+//
+// Messages sent from extension to feedback server as JSON.
+
+syntax = "proto2";
+
+package userfeedback;
+
+import "common.proto";
+import "dom.proto";
+import "math.proto";
+import "web.proto";
+
+// Sent along with request for extension page when user attempts to open
+// feedback tab.
+message ExtensionPageRequestParams {
+
+ required ExtensionDetails extension_details = 1;
+
+ // Url of the page (without request params) that user wants to open
+ // feedback tool for.
+ required string url = 2;
+};
+
+message PostedScreenshot {
+
+ required string mime_type = 1;
+
+ required Dimensions dimensions = 2;
+
+ optional string base64_content = 3;
+
+ optional bytes binary_content = 4;
+};
+
+// Contains data about possible errors on the client side.
+// Describes number of attempts to send feedback and possible error codes/
+// exceptions which occured.
+message ExtensionErrors {
+
+ required int32 number_of_attempts = 1;
+
+ required string errors = 2;
+};
+
+// Sent when user hits final submit button in external extension.
+// NOTE: Field numbers for ExternalExtensionSubmit and InternalExtensionSubmit
+// share the same number space, because we don't want submission from internal
+// extension to the external address, or submission from external extension to
+// internal address, work by accident, partially work, or break in an odd way.
+// If the field numbers were overlapping for both protos, such cross-submission
+// might work, due to the specifics of JsPbLite.
+message ExternalExtensionSubmit {
+
+ required CommonData common_data = 1;
+
+ required WebData web_data = 2;
+
+ required int32 type_id = 3;
+
+ optional PostedScreenshot screenshot = 4;
+
+ optional HtmlDocument html_document_structure = 5;
+
+ optional ExtensionErrors extension_errors = 13;
+};
+
+// Sent when user hits final submit button in internal extension.
+// NOTE: Field numbers for ExternalExtensionSubmit and InternalExtensionSubmit
+// share the same number space. See comment for ExternalExtensionSubmit.
+message InternalExtensionSubmit {
+
+ required CommonData common_data = 6;
+
+ required WebData web_data = 7;
+
+ optional int32 type_id = 8;
+
+ optional PostedScreenshot screenshot = 9;
+
+ optional HtmlDocument html_document_structure = 10;
+
+ optional InternalWebData internal_data = 11;
+
+ optional ExtensionErrors extension_errors = 12;
+};
+
+// A query for suggestions, sent when the user hits the preview button.
+message SuggestQuery {
+
+ required CommonData common_data = 1;
+
+ required WebData web_data = 2;
+
+ required int32 type_id = 3;
+
+ optional HtmlDocument html_document_structure = 4;
+};
diff --git a/chrome/browser/userfeedback/proto/math.proto b/chrome/browser/userfeedback/proto/math.proto
new file mode 100644
index 0000000..c189967
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/math.proto
@@ -0,0 +1,22 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: micapolos@google.com (Michal Pociecha-Los)
+//
+// Messages containing common math data structures.
+
+syntax = "proto2";
+
+package userfeedback;
+
+// 2D Dimensions.
+message Dimensions {
+ required float width = 1;
+ required float height = 2;
+};
+
+// Axis-aligned rectangle in 2D space.
+message Rectangle {
+ required float left = 1;
+ required float top = 2;
+ required float width = 3;
+ required float height = 4;
+};
diff --git a/chrome/browser/userfeedback/proto/web.proto b/chrome/browser/userfeedback/proto/web.proto
new file mode 100644
index 0000000..fb9f6af
--- /dev/null
+++ b/chrome/browser/userfeedback/proto/web.proto
@@ -0,0 +1,70 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+// Author: jaceks@google.com (Jacek Surazski)
+
+syntax = "proto2";
+
+package userfeedback;
+
+// Data present in Web related feedbacks
+
+import "annotations.proto";
+import "config.proto";
+import "dom.proto";
+import "math.proto";
+
+// Data present in feedbacks sent from web extension.
+message WebData {
+ // Data captured from DOM Navigator object.
+ optional Navigator navigator = 1;
+
+ // Details of the extension from which this data was sent.
+ optional ExtensionDetails extension_details = 2;
+
+ // The URL of the document.
+ // Useful when user opts out from sending html structure.
+ optional string url = 3;
+
+ // A list of annotations.
+ repeated Annotation annotation = 4;
+
+ // The ID of the suggestion selected by the user.
+ // Possible values:
+ // - Not set if no suggestions were shown, either because the version of
+ // the client did not support suggestions, suggestions were disabled or
+ // no matching suggestions were found.
+ // - NONE_OF_THE_ABOVE if the user has chosen "None of the above".
+ // - Empty string if suggestions were shown but the user hasn't chosen
+ // any of them (and also she hasn't chosen "None of the above").
+ // - Actual suggestion identifier as returned from the server.
+ optional string suggestion_id = 5;
+
+ repeated ProductSpecificData product_specific_data = 6;
+};
+
+message ExtensionDetails {
+ // Indicates browser and mpm release.
+ required string extension_version = 1;
+
+ required string protocol_version = 2;
+};
+
+// Additional data sent by the internal version.
+message InternalWebData {
+ // List of user names in google.com domain to which feedback should be sent
+ // directly apart from submitting it to server.
+ repeated string email_receiver = 1;
+
+ // Subject of the problem entered by user.
+ optional string subject = 2;
+
+ // If this flag is set then product support team should be notified
+ // immediately.
+ optional bool DEPRECATED_urgent = 3 [default = false];
+};
+
+// Product specific data. Contains one key/value pair that is specific to the
+// product for which feedback is submitted.
+message ProductSpecificData {
+ required string key = 1;
+ optional string value = 2;
+};
diff --git a/chrome/browser/views/bug_report_view.cc b/chrome/browser/views/bug_report_view.cc
index 4903c75..2ae2f67 100644
--- a/chrome/browser/views/bug_report_view.cc
+++ b/chrome/browser/views/bug_report_view.cc
@@ -12,6 +12,7 @@
#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/safe_browsing/safe_browsing_util.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
@@ -42,6 +43,8 @@ using views::GridLayout;
// Report a bug data version.
static const int kBugReportVersion = 1;
+static const int kScreenImageRadioGroup = 2;
+
// Number of lines description field can display at one time.
static const int kDescriptionLines = 5;
@@ -105,9 +108,14 @@ void ShowBugReportView(views::Window* parent,
win_util::GrabWindowSnapshot(parent->GetNativeWindow(), screenshot_png);
#endif
+ // Get the size of the parent window to capture screenshot dimensions
+ gfx::Rect screenshot_size = parent->GetBounds();
+
+
// The BugReportView takes ownership of the png data, and will dispose of
// it in its destructor.
view->set_png_data(screenshot_png);
+ view->set_screenshot_size(screenshot_size);
// Create and show the dialog.
views::Window::CreateChromeWindow(parent->GetNativeWindow(), gfx::Rect(),
@@ -184,6 +192,25 @@ void BugReportView::SetupControl() {
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);
+ last_screenshot_iv_ = new views::ImageView();
+
+ include_new_screen_image_radio_ = new views::RadioButton(
+ l10n_util::GetString(IDS_BUGREPORT_INCLUDE_NEW_SCREEN_IMAGE),
+ kScreenImageRadioGroup);
+
+ include_system_information_checkbox_ = new views::Checkbox(
+ l10n_util::GetString(IDS_BUGREPORT_INCLUDE_SYSTEM_INFORMATION_CHKBOX));
+ system_information_url_ = new views::Link(
+ l10n_util::GetString(IDS_BUGREPORT_SYSTEM_INFORMATION_URL_TEXT));
+ system_information_url_->SetController(this);
+
+ include_last_screen_image_radio_->SetChecked(true);
+ include_system_information_checkbox_->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);
@@ -232,11 +259,31 @@ void BugReportView::SetupControl() {
// 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,
+ layout->AddView(include_last_screen_image_radio_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ // new screenshot
+ layout->StartRow(0, column_set_id);
+ layout->SkipColumns(1);
+ layout->AddView(include_new_screen_image_radio_);
+ layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
+
+ // Checkbox for system information
+ layout->StartRow(0, column_set_id);
+ layout->SkipColumns(1);
+ layout->AddView(include_system_information_checkbox_);
+
+ // TODO(rkc): Add a link once we're pulling system info, to it
+#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);
}
@@ -247,6 +294,30 @@ gfx::Size BugReportView::GetPreferredSize() {
IDS_BUGREPORT_DIALOG_HEIGHT_LINES));
}
+
+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_last_screen_image_radio_->SetEnabled(!is_phishing_report);
+ include_new_screen_image_radio_->SetEnabled(!is_phishing_report);
+
+ include_system_information_checkbox_->SetEnabled(!is_phishing_report);
+ include_system_information_checkbox_->SetChecked(!is_phishing_report);
+
+ system_information_url_->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) {
@@ -265,12 +336,8 @@ void BugReportView::ItemChanged(views::Combobox* combobox,
description_text_->SetText(WideToUTF16Hack(old_report_text_));
old_report_text_.clear();
}
- include_page_source_checkbox_->SetEnabled(!is_phishing_report);
- include_page_source_checkbox_->SetChecked(!is_phishing_report);
- if (include_page_image_checkbox_) {
- include_page_image_checkbox_->SetEnabled(!is_phishing_report);
- include_page_image_checkbox_->SetChecked(!is_phishing_report);
- }
+
+ UpdateReportingControls(is_phishing_report);
GetDialogClientView()->UpdateDialogButtons();
}
@@ -334,13 +401,35 @@ bool BugReportView::Accept() {
problem_type_,
UTF16ToUTF8(page_url_text_->text()),
UTF16ToUTF8(description_text_->text()),
+#if defined(OS_CHROMEOS)
+ include_new_screen_image_radio_->checked() && png_data_.get() ?
+#else
include_page_image_checkbox_->checked() && png_data_.get() ?
+#endif
reinterpret_cast<const char *>(&((*png_data_.get())[0])) : NULL,
- png_data_->size());
+ png_data_->size(), screenshot_size_.width(),
+ screenshot_size_.height());
}
return true;
}
+#if defined(OS_CHROMEOS)
+void BugReportView::LinkActivated(views::Link* source,
+ int event_flags) {
+ GURL url;
+ if (source == system_information_url_) {
+ url = GURL(l10n_util::GetStringUTF16(IDS_BUGREPORT_SYSTEM_INFORMATION_URL));
+ } else {
+ NOTREACHED() << "Unknown link source";
+ return;
+ }
+
+ Browser* browser = BrowserList::GetLastActive();
+ 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
index 7d641b1..1fa3e5d 100644
--- a/chrome/browser/views/bug_report_view.h
+++ b/chrome/browser/views/bug_report_view.h
@@ -6,9 +6,13 @@
#define CHROME_BROWSER_VIEWS_BUG_REPORT_VIEW_H_
#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"
@@ -17,6 +21,8 @@ class Checkbox;
class Label;
class Throbber;
class Window;
+class RadioButton;
+class Link;
}
class Profile;
@@ -35,6 +41,9 @@ class BugReportComboBoxModel;
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:
explicit BugReportView(Profile* profile, TabContents* tab);
@@ -44,6 +53,12 @@ class BugReportView : public views::View,
void set_png_data(std::vector<unsigned char> *png_data) {
png_data_.reset(png_data);
};
+ void set_screenshot_size(const gfx::Rect& screenshot_size) {
+ screenshot_size_ = screenshot_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();
@@ -58,6 +73,11 @@ class BugReportView : public views::View,
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);
+#endif
+
// Overridden from views::DialogDelegate:
virtual std::wstring GetDialogButtonLabel(
MessageBoxFlags::DialogButton button) const;
@@ -96,13 +116,23 @@ class BugReportView : public views::View,
views::Label* description_label_;
views::Textfield* description_text_;
views::Checkbox* include_page_source_checkbox_;
+#if defined(OS_CHROMEOS)
+ views::RadioButton* include_last_screen_image_radio_;
+ views::ImageView* last_screenshot_iv_;
+ views::RadioButton* include_new_screen_image_radio_;
+ views::Checkbox* include_system_information_checkbox_;
+ views::Link* system_information_url_;
+#endif
+ // TODO: #else this once the BugReport function is fixed up
views::Checkbox* include_page_image_checkbox_;
+
scoped_ptr<BugReportComboBoxModel> bug_type_model_;
Profile* profile_;
std::wstring version_;
+ gfx::Rect screenshot_size_;
scoped_ptr< std::vector<unsigned char> > png_data_;
TabContents* tab_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index b4c8817..6ebffd5 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -21,6 +21,7 @@
'browser/sync/protocol/sync_proto.gyp:sync_proto_cpp',
'syncapi',
'theme_resources',
+ 'userfeedback_proto',
'../app/app.gyp:app_resources',
'../app/app.gyp:app_strings',
'../media/media.gyp:media',
@@ -298,6 +299,14 @@
'browser/browsing_instance.h',
'browser/bug_report_util.cc',
'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/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',
+ '<(protoc_out_dir)/chrome/browser/userfeedback/proto/web.pb.cc',
'browser/cancelable_request.cc',
'browser/cancelable_request.h',
'browser/cert_store.cc',
@@ -3180,6 +3189,7 @@
],
'dependencies': [
'../third_party/protobuf2/protobuf.gyp:protobuf_lite',
+ #'../third_party/protobuf2/protobuf.gyp:protobuf',
'../third_party/protobuf2/protobuf.gyp:protoc#host',
'../third_party/chromeos_login_manager/chromeos_login_manager/chromeos_login_manager.gyp:session',
'../third_party/chromeos_login_manager/chromeos_login_manager/chromeos_login_manager.gyp:emit_login_prompt_ready',
@@ -3428,6 +3438,61 @@
},
]
},
+ {
+ # Protobuf compiler / generate rule for feedback
+ 'target_name': 'userfeedback_proto',
+ 'type': 'none',
+ 'sources': [
+ 'browser/userfeedback/proto/annotations.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',
+ 'browser/userfeedback/proto/web.proto',
+ ],
+ 'rules': [
+ {
+ 'rule_name': 'genproto',
+ 'extension': 'proto',
+ 'inputs': [
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
+ ],
+ 'variables': {
+ # The protoc compiler requires a proto_path argument with the
+ # directory containing the .proto file.
+ # There's no generator variable that corresponds to this, so fake it.
+ 'rule_input_relpath': 'browser/userfeedback/proto',
+ },
+ 'outputs': [
+ '<(protoc_out_dir)/chrome/<(rule_input_relpath)/<(RULE_INPUT_ROOT).pb.h',
+ '<(protoc_out_dir)/chrome/<(rule_input_relpath)/<(RULE_INPUT_ROOT).pb.cc',
+ ],
+ 'action': [
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
+ '--proto_path=./<(rule_input_relpath)',
+ './<(rule_input_relpath)/<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)',
+ '--cpp_out=<(protoc_out_dir)/chrome/<(rule_input_relpath)',
+ ],
+ 'message': 'Generating C++ code from <(RULE_INPUT_PATH)',
+ },
+ ],
+ 'dependencies': [
+ '../third_party/protobuf2/protobuf.gyp:protobuf',
+ '../third_party/protobuf2/protobuf.gyp:protoc#host',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(protoc_out_dir)',
+ ]
+ },
+ 'export_dependent_settings': [
+ '../third_party/protobuf2/protobuf.gyp:protobuf',
+ ],
+ 'dependencies': [
+ '../third_party/protobuf2/protobuf.gyp:protobuf',
+ ],
+ },
],
}
diff --git a/third_party/protobuf2/protobuf.gyp b/third_party/protobuf2/protobuf.gyp
index c812d52..c1a9e39 100644
--- a/third_party/protobuf2/protobuf.gyp
+++ b/third_party/protobuf2/protobuf.gyp
@@ -95,7 +95,7 @@
{
'target_name': 'protobuf',
'type': '<(library)',
- 'toolsets': ['host'],
+ 'toolsets': ['host','target'],
'sources': [
'src/src/google/protobuf/descriptor.h',
'src/src/google/protobuf/descriptor.pb.h',