Bug 1160424 - [Decoder Doctor] Show notification UI when a requested codec is missing but downloadable. r?gijs
MozReview-Commit-ID: BHPpLM96cg3
rename from browser/base/content/browser-eme.js
rename to browser/base/content/browser-media.js
--- a/browser/base/content/browser-eme.js
+++ b/browser/base/content/browser-media.js
@@ -172,12 +172,95 @@ var gEMEHandler = {
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener])
};
XPCOMUtils.defineLazyGetter(gEMEHandler, "_brandShortName", function() {
return document.getElementById("bundle_brand").getString("brandShortName");
});
+var gDecoderDoctorHandler = {
+ shouldShowNotification(type) {
+ return type == "adobe-cdm-not-found" ||
+ type == "adobe-cdm-not-activated" ||
+ type == "platform-decoder-not-found";
+ },
+
+ shouldShowLearnMoreButton() {
+ return AppConstants.platform != "linux";
+ },
+
+ getLabelForNotificationBox(type) {
+ if (type == "adobe-cdm-not-found" &&
+ AppConstants.platform == "win") {
+ if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+ // We supply our own Learn More link so we don't need to populate the message here.
+ return gNavigatorBundle.getFormattedString("emeNotifications.drmContentDisabled.message", [""]);
+ }
+ return gNavigatorBundle.getString("decoder.noCodecs.message");
+ }
+ if (type == "adobe-cdm-not-activated" &&
+ AppConstants.platform == "win") {
+ if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+ return gNavigatorBundle.getString("decoder.noCodecsXP.message");
+ }
+ return gNavigatorBundle.getString("decoder.noCodecs.message");
+ }
+ if (type == "platform-decoder-not-found") {
+ if (AppConstants.isPlatformAndVersionAtLeast("win", "6")) {
+ return gNavigatorBundle.getString("decoder.noHWAcceleration.message");
+ }
+ if (AppConstants.platform == "linux") {
+ return gNavigatorBundle.getString("decoder.noCodecsLinux.message");
+ }
+ }
+ return "";
+ },
+
+ receiveMessage({target: browser, data: data}) {
+ let box = gBrowser.getNotificationBox(browser);
+ let notificationId = "decoder-doctor-notification";
+ if (box.getNotificationWithValue(notificationId)) {
+ return;
+ }
+
+ let parsedData;
+ try {
+ parsedData = JSON.parse(data);
+ } catch (ex) {
+ Cu.reportError("Malformed Decoder Doctor message with data: " + data);
+ return;
+ }
+ let {type: type} = parsedData;
+ type = type.toLowerCase();
+ if (!gDecoderDoctorHandler.shouldShowNotification(type)) {
+ return;
+ }
+
+ let title = gDecoderDoctorHandler.getLabelForNotificationBox(type);
+ let buttons = [];
+ if (gDecoderDoctorHandler.shouldShowLearnMoreButton()) {
+ buttons.push({
+ label: gNavigatorBundle.getString("decoder.noCodecs.button"),
+ accessKey: gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
+ callback() {
+ let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
+ openUILinkIn(baseURL + "fix-video-audio-problems-firefox-windows", "tab");
+ }
+ });
+ }
+
+ box.appendNotification(
+ title,
+ notificationId,
+ "", // This uses the info icon as specified below.
+ box.PRIORITY_INFO_LOW,
+ buttons
+ );
+ },
+}
+
+window.messageManager.addMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
window.messageManager.addMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
window.addEventListener("unload", function() {
window.messageManager.removeMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
+ window.messageManager.removeMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
}, false);
--- a/browser/base/content/global-scripts.inc
+++ b/browser/base/content/global-scripts.inc
@@ -10,21 +10,21 @@
<script type="application/javascript" src="chrome://browser/content/customizableui/panelUI.js"/>
<script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
<script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-addons.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-ctrlTab.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-customization.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-devedition.js"/>
-<script type="application/javascript" src="chrome://browser/content/browser-eme.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-feeds.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-fullScreen.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-fullZoom.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-gestureSupport.js"/>
+<script type="application/javascript" src="chrome://browser/content/browser-media.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-places.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-plugins.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-refreshblocker.js"/>
#ifdef MOZ_SAFE_BROWSING
<script type="application/javascript" src="chrome://browser/content/browser-safebrowsing.js"/>
#endif
<script type="application/javascript" src="chrome://browser/content/browser-sidebar.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-social.js"/>
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -311,16 +311,18 @@ skip-if = os == 'win'
[browser_contextmenu.js]
tags = fullscreen
skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug 513558
[browser_contextmenu_input.js]
skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug 513558
[browser_ctrlTab.js]
[browser_datachoices_notification.js]
skip-if = !datareporting
+[browser_decoderDoctor.js]
+skip-if = os == "mac" # decoder doctor isn't implemented on osx
[browser_devedition.js]
[browser_devices_get_user_media.js]
skip-if = buildapp == 'mulet' || (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_about_urls.js]
skip-if = e10s && debug
[browser_devices_get_user_media_in_frame.js]
[browser_discovery.js]
[browser_double_close_tab.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_decoderDoctor.js
@@ -0,0 +1,94 @@
+"use strict";
+
+function* test_decoder_doctor_notification(type, notificationMessage, options) {
+ yield BrowserTestUtils.withNewTab({ gBrowser }, function*(browser) {
+ let awaitNotificationBar =
+ BrowserTestUtils.waitForNotificationBar(gBrowser, browser, "decoder-doctor-notification");
+
+ yield ContentTask.spawn(browser, type, function*(type) {
+ Services.obs.notifyObservers(content.window,
+ "decoder-doctor-notification",
+ JSON.stringify({type: type}));
+ });
+
+ let notification;
+ try {
+ notification = yield awaitNotificationBar;
+ } catch (ex) {
+ ok(false, ex);
+ return;
+ }
+ ok(notification, "Got decoder-doctor-notification notification");
+
+ is(notification.getAttribute("label"), notificationMessage,
+ "notification message should match expectation");
+ let button = notification.childNodes[0];
+ if (options && options.noLearnMoreButton) {
+ ok(!button, "There should not be a Learn More button");
+ return;
+ }
+
+ is(button.getAttribute("label"), gNavigatorBundle.getString("decoder.noCodecs.button"),
+ "notification button should be 'Learn more'");
+ is(button.getAttribute("accesskey"), gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
+ "notification button should have accesskey");
+
+ let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
+ let url = baseURL + "fix-video-audio-problems-firefox-windows";
+ let awaitNewTab = BrowserTestUtils.waitForNewTab(gBrowser, url);
+ button.click();
+ let sumoTab = yield awaitNewTab;
+ yield BrowserTestUtils.removeTab(sumoTab);
+ });
+}
+
+add_task(function* test_adobe_cdm_not_found() {
+ // This is only sent on Windows.
+ if (AppConstants.platform != "win") {
+ return;
+ }
+
+ let message;
+ if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+ message = gNavigatorBundle.getFormattedString("emeNotifications.drmContentDisabled.message", [""]);
+ } else {
+ message = gNavigatorBundle.getString("decoder.noCodecs.message");
+ }
+
+ yield test_decoder_doctor_notification("adobe-cdm-not-found", message);
+});
+
+add_task(function* test_adobe_cdm_not_activated() {
+ // This is only sent on Windows.
+ if (AppConstants.platform != "win") {
+ return;
+ }
+
+ let message;
+ if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+ message = gNavigatorBundle.getString("decoder.noCodecsXP.message");
+ } else {
+ message = gNavigatorBundle.getString("decoder.noCodecs.message");
+ }
+
+ yield test_decoder_doctor_notification("adobe-cdm-not-activated", message);
+});
+
+add_task(function* test_platform_decoder_not_found() {
+ // Not sent on Windows XP.
+ if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+ return;
+ }
+
+ let message;
+ let isLinux = AppConstants.platform == "linux";
+ if (isLinux) {
+ message = gNavigatorBundle.getString("decoder.noCodecsLinux.message");
+ } else {
+ message = gNavigatorBundle.getString("decoder.noHWAcceleration.message");
+ }
+
+ yield test_decoder_doctor_notification("platform-decoder-not-found",
+ message,
+ {noLearnMoreButton: isLinux});
+});
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -74,22 +74,22 @@ browser.jar:
* content/browser/browser.css (content/browser.css)
content/browser/browser.js (content/browser.js)
* content/browser/browser.xul (content/browser.xul)
content/browser/browser-addons.js (content/browser-addons.js)
content/browser/browser-ctrlTab.js (content/browser-ctrlTab.js)
content/browser/browser-customization.js (content/browser-customization.js)
content/browser/browser-data-submission-info-bar.js (content/browser-data-submission-info-bar.js)
content/browser/browser-devedition.js (content/browser-devedition.js)
- content/browser/browser-eme.js (content/browser-eme.js)
content/browser/browser-feeds.js (content/browser-feeds.js)
content/browser/browser-fullScreen.js (content/browser-fullScreen.js)
content/browser/browser-fullZoom.js (content/browser-fullZoom.js)
content/browser/browser-fxaccounts.js (content/browser-fxaccounts.js)
content/browser/browser-gestureSupport.js (content/browser-gestureSupport.js)
+ content/browser/browser-media.js (content/browser-media.js)
content/browser/browser-places.js (content/browser-places.js)
content/browser/browser-plugins.js (content/browser-plugins.js)
content/browser/browser-refreshblocker.js (content/browser-refreshblocker.js)
#ifdef MOZ_SAFE_BROWSING
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
#endif
content/browser/browser-sidebar.js (content/browser-sidebar.js)
content/browser/browser-social.js (content/browser-social.js)
--- a/browser/modules/ContentObservers.jsm
+++ b/browser/modules/ContentObservers.jsm
@@ -22,16 +22,24 @@ Cu.import("resource://gre/modules/Servic
var gEMEUIObserver = function(subject, topic, data) {
let win = subject.top;
let mm = getMessageManagerForWindow(win);
if (mm) {
mm.sendAsyncMessage("EMEVideo:ContentMediaKeysRequest", data);
}
};
+var gDecoderDoctorObserver = function(subject, topic, data) {
+ let win = subject.top;
+ let mm = getMessageManagerForWindow(win);
+ if (mm) {
+ mm.sendAsyncMessage("DecoderDoctor:Notification", data);
+ }
+};
+
function getMessageManagerForWindow(aContentWindow) {
let ir = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor);
try {
// If e10s is disabled, this throws NS_NOINTERFACE for closed tabs.
return ir.getInterface(Ci.nsIContentFrameMessageManager);
@@ -39,8 +47,9 @@ function getMessageManagerForWindow(aCon
if (e.result == Cr.NS_NOINTERFACE) {
return null;
}
throw e;
}
}
Services.obs.addObserver(gEMEUIObserver, "mediakeys-request", false);
+Services.obs.addObserver(gDecoderDoctorObserver, "decoder-doctor-notification", false);
--- a/testing/eslint-plugin-mozilla/lib/rules/import-browserjs-globals.js
+++ b/testing/eslint-plugin-mozilla/lib/rules/import-browserjs-globals.js
@@ -29,21 +29,21 @@ const SCRIPTS = [
"browser/components/downloads/content/indicator.js",
"browser/components/customizableui/content/panelUI.js",
"toolkit/obsolete/content/inlineSpellCheckUI.js",
"toolkit/components/viewsource/content/viewSourceUtils.js",
"browser/base/content/browser-addons.js",
"browser/base/content/browser-ctrlTab.js",
"browser/base/content/browser-customization.js",
"browser/base/content/browser-devedition.js",
- "browser/base/content/browser-eme.js",
"browser/base/content/browser-feeds.js",
"browser/base/content/browser-fullScreen.js",
"browser/base/content/browser-fullZoom.js",
"browser/base/content/browser-gestureSupport.js",
+ "browser/base/content/browser-media.js",
"browser/base/content/browser-places.js",
"browser/base/content/browser-plugins.js",
"browser/base/content/browser-refreshblocker.js",
"browser/base/content/browser-safebrowsing.js",
"browser/base/content/browser-sidebar.js",
"browser/base/content/browser-social.js",
"browser/base/content/browser-syncui.js",
"browser/base/content/browser-tabsintitlebar.js",