Bug 1343442 - Handle decode-error/warning in browser-media.js - r?gijs
Open webcompat.com in new tab, similar to what "Report Site Issue" button does.
MozReview-Commit-ID: 1ESOY3upHgc
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -202,29 +202,43 @@ let gDecoderDoctorHandler = {
}
if (type == "cannot-initialize-pulseaudio") {
return gNavigatorBundle.getString("decoder.noPulseAudio.message");
}
if (type == "unsupported-libavcodec" &&
AppConstants.platform == "linux") {
return gNavigatorBundle.getString("decoder.unsupportedLibavcodec.message");
}
+ if (type == "decode-error") {
+ return gNavigatorBundle.getString("decoder.decodeError.message");
+ }
+ if (type == "decode-warning") {
+ return gNavigatorBundle.getString("decoder.decodeWarning.message");
+ }
return "";
},
getSumoForLearnHowButton(type) {
- if (AppConstants.platform == "win") {
+ if (type == "platform-decoder-not-found" &&
+ AppConstants.platform == "win") {
return "fix-video-audio-problems-firefox-windows";
}
if (type == "cannot-initialize-pulseaudio") {
return "fix-common-audio-and-video-issues";
}
return "";
},
+ getEndpointForReportIssueButton(type) {
+ if (type == "decode-error" || type == "decode-warning") {
+ return Services.prefs.getStringPref("media.decoder-doctor.new-issue-endpoint", "");
+ }
+ return "";
+ },
+
receiveMessage({target: browser, data: data}) {
let box = gBrowser.getNotificationBox(browser);
let notificationId = "decoder-doctor-notification";
if (box.getNotificationWithValue(notificationId)) {
return;
}
let parsedData;
@@ -233,89 +247,119 @@ let gDecoderDoctorHandler = {
} catch (ex) {
Cu.reportError("Malformed Decoder Doctor message with data: " + data);
return;
}
// parsedData (the result of parsing the incoming 'data' json string)
// contains analysis information from Decoder Doctor:
// - 'type' is the type of issue, it determines which text to show in the
// infobar.
+ // - 'isSolved' is true when the notification actually indicates the
+ // resolution of that issue, to be reported as telemetry.
// - 'decoderDoctorReportId' is the Decoder Doctor issue identifier, to be
// used here as key for the telemetry (counting infobar displays,
// "Learn how" buttons clicks, and resolutions) and for the prefs used
// to store at-issue formats.
// - 'formats' contains a comma-separated list of formats (or key systems)
// that suffer the issue. These are kept in a pref, which the backend
// uses to later find when an issue is resolved.
- // - 'isSolved' is true when the notification actually indicates the
- // resolution of that issue, to be reported as telemetry.
- let {type, isSolved, decoderDoctorReportId, formats} = parsedData;
+ // - 'decodeIssue' is a description of the decode error/warning.
+ // - 'resourceURL' is the resource with the issue.
+ let {type, isSolved, decoderDoctorReportId,
+ formats, decodeIssue, docURL, resourceURL} = parsedData;
type = type.toLowerCase();
// Error out early on invalid ReportId
if (!(/^\w+$/mi).test(decoderDoctorReportId)) {
return
}
let title = gDecoderDoctorHandler.getLabelForNotificationBox(type);
if (!title) {
return;
}
// We keep the list of formats in prefs for the sake of the decoder itself,
// which reads it to determine when issues get solved for these formats.
- // (Writing prefs from e10s content is now allowed.)
- let formatsPref = "media.decoder-doctor." + decoderDoctorReportId + ".formats";
+ // (Writing prefs from e10s content is not allowed.)
+ let formatsPref = formats &&
+ "media.decoder-doctor." + decoderDoctorReportId + ".formats";
let buttonClickedPref = "media.decoder-doctor." + decoderDoctorReportId + ".button-clicked";
let histogram =
Services.telemetry.getKeyedHistogramById("DECODER_DOCTOR_INFOBAR_STATS");
- let formatsInPref = Services.prefs.getPrefType(formatsPref) &&
- Services.prefs.getCharPref(formatsPref);
+ let formatsInPref = formats &&
+ Services.prefs.getCharPref(formatsPref, "");
if (!isSolved) {
- if (!formats) {
- Cu.reportError("Malformed Decoder Doctor unsolved message with no formats");
+ if (formats) {
+ if (!formatsInPref) {
+ Services.prefs.setCharPref(formatsPref, formats);
+ histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN_FIRST);
+ } else {
+ // Split existing formats into an array of strings.
+ let existing = formatsInPref.split(",").map(x => x.trim());
+ // Keep given formats that were not already recorded.
+ let newbies = formats.split(",").map(x => x.trim())
+ .filter(x => !existing.includes(x));
+ // And rewrite pref with the added new formats (if any).
+ if (newbies.length) {
+ Services.prefs.setCharPref(formatsPref,
+ existing.concat(newbies).join(", "));
+ }
+ }
+ } else if (!decodeIssue) {
+ Cu.reportError("Malformed Decoder Doctor unsolved message with no formats nor decode issue");
return;
}
- if (!formatsInPref) {
- Services.prefs.setCharPref(formatsPref, formats);
- histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN_FIRST);
- } else {
- // Split existing formats into an array of strings.
- let existing = formatsInPref.split(",").map(x => x.trim());
- // Keep given formats that were not already recorded.
- let newbies = formats.split(",").map(x => x.trim())
- .filter(x => !existing.includes(x));
- // And rewrite pref with the added new formats (if any).
- if (newbies.length) {
- Services.prefs.setCharPref(formatsPref,
- existing.concat(newbies).join(", "));
- }
- }
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN);
let buttons = [];
let sumo = gDecoderDoctorHandler.getSumoForLearnHowButton(type);
if (sumo) {
buttons.push({
label: gNavigatorBundle.getString("decoder.noCodecs.button"),
accessKey: gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
callback() {
- let clickedInPref = Services.prefs.getPrefType(buttonClickedPref) &&
- Services.prefs.getBoolPref(buttonClickedPref);
+ let clickedInPref =
+ Services.prefs.getBoolPref(buttonClickedPref, false);
if (!clickedInPref) {
Services.prefs.setBoolPref(buttonClickedPref, true);
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED_FIRST);
}
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED);
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
openUILinkIn(baseURL + sumo, "tab");
}
});
}
+ let endpoint = gDecoderDoctorHandler.getEndpointForReportIssueButton(type);
+ if (endpoint) {
+ buttons.push({
+ label: gNavigatorBundle.getString("decoder.decodeError.button"),
+ accessKey: gNavigatorBundle.getString("decoder.decodeError.accesskey"),
+ callback() {
+ let clickedInPref =
+ Services.prefs.getBoolPref(buttonClickedPref, false);
+ if (!clickedInPref) {
+ Services.prefs.setBoolPref(buttonClickedPref, true);
+ histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED_FIRST);
+ }
+ histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED);
+
+ let params = new URLSearchParams;
+ params.append("url", docURL);
+ params.append("problem_type", "video_bug");
+ params.append("src", "media-decode-error");
+ params.append("details",
+ "Technical Information:\n" + decodeIssue +
+ (resourceURL ? ("\nResource: " + resourceURL) : ""));
+ openUILinkIn(endpoint + "?" + params.toString(), "tab");
+ }
+ });
+ }
box.appendNotification(
title,
notificationId,
"", // This uses the info icon as specified below.
box.PRIORITY_INFO_LOW,
buttons
);
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -840,16 +840,21 @@ pendingCrashReports.alwaysSend = Always
decoder.noCodecs.button = Learn how
decoder.noCodecs.accesskey = L
decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
decoder.noPulseAudio.message = To play audio, you may need to install the required PulseAudio software.
decoder.unsupportedLibavcodec.message = libavcodec may be vulnerable or is not supported, and should be updated to play video.
+decoder.decodeError.message = An error occurred while decoding a media resource.
+decoder.decodeError.button = Report Site Issue
+decoder.decodeError.accesskey = R
+decoder.decodeWarning.message = A recoverable error occurred while decoding a media resource.
+
# LOCALIZATION NOTE (captivePortal.infoMessage3):
# Shown in a notification bar when we detect a captive portal is blocking network access
# and requires the user to log in before browsing.
captivePortal.infoMessage3 = You must log in to this network before you can access the Internet.
# LOCALIZATION NOTE (captivePortal.showLoginPage2):
# The label for a button shown in the info bar in all tabs except the login page tab.
# The button shows the portal login page tab when clicked.
captivePortal.showLoginPage2 = Open Network Login Page
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -389,16 +389,18 @@ pref("media.gmp.storage.version.expected
pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMF,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec,MediaDecodeError");
#else
pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMF,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec");
#endif
// Whether we report partial failures.
pref("media.decoder-doctor.verbose", false);
// Whether DD should consider WMF-disabled a WMF failure, useful for testing.
pref("media.decoder-doctor.wmf-disabled-is-failure", false);
+// URL to report decode issues
+pref("media.decoder-doctor.new-issue-endpoint", "https://webcompat.com/issues/new");
// Whether to suspend decoding of videos in background tabs.
#ifdef NIGHTLY_BUILD
pref("media.suspend-bkgnd-video.enabled", true);
#else
pref("media.suspend-bkgnd-video.enabled", false);
#endif
// Delay, in ms, from time window goes to background to suspending