Bug 1111148 - show doorhanger for EME being played back, r=florian
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 04 Feb 2015 17:13:38 +0000
changeset 250248 55823773c733
parent 250247 38ce715f4de4
child 250249 0631cc897937
push id4526
push usergijskruitbosch@gmail.com
push date2015-03-05 00:08 +0000
treeherdermozilla-beta@0e44d113855f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1111148
milestone37.0
Bug 1111148 - show doorhanger for EME being played back, r=florian
browser/base/content/browser-eme.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/content.js
browser/modules/ContentObservers.jsm
browser/modules/moz.build
browser/themes/linux/browser.css
browser/themes/linux/jar.mn
browser/themes/osx/browser.css
browser/themes/osx/jar.mn
browser/themes/shared/drm-icon.svg
browser/themes/windows/browser.css
browser/themes/windows/jar.mn
new file mode 100644
--- /dev/null
+++ b/browser/base/content/browser-eme.js
@@ -0,0 +1,36 @@
+# -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+function gEMEListener(msg /*{target: browser, data: data} */) {
+  let browser = msg.target;
+  let notificationId = "drmContentPlaying";
+  // Don't need to show if disabled, nor reshow if it's already there
+  if (!Services.prefs.getBoolPref("browser.eme.ui.enabled") ||
+      PopupNotifications.getNotification(notificationId, browser)) {
+    return;
+  }
+
+  let msgId = "emeNotifications.drmContentPlaying.message";
+  let brandName = document.getElementById("bundle_brand").getString("brandShortName");
+  let message = gNavigatorBundle.getFormattedString(msgId, [msg.data.drmProvider, brandName]);
+  let anchorId = "eme-notification-icon";
+
+  let mainAction = {
+    label: gNavigatorBundle.getString("emeNotifications.drmContentPlaying.button.label"),
+    accessKey: gNavigatorBundle.getString("emeNotifications.drmContentPlaying.button.accesskey"),
+    callback: function() { openPreferences("paneContent"); },
+    dismiss: true
+  };
+  let options = {
+    dismissed: true,
+    eventCallback: aTopic => aTopic == "swapping",
+  };
+  PopupNotifications.show(browser, notificationId, message, anchorId, mainAction, null, options);
+};
+
+window.messageManager.addMessageListener("EMEVideo:MetadataLoaded", gEMEListener);
+window.addEventListener("unload", function() {
+  window.messageManager.removeMessageListener("EMEVideo:MetadataLoaded", gEMEListener);
+}, false);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -203,16 +203,17 @@ let gInitialPages = [
   "about:welcomeback",
   "about:sessionrestore"
 ];
 
 #include browser-addons.js
 #include browser-ctrlTab.js
 #include browser-customization.js
 #include browser-devedition.js
+#include browser-eme.js
 #include browser-feeds.js
 #include browser-fullScreen.js
 #include browser-fullZoom.js
 #include browser-gestureSupport.js
 #include browser-loop.js
 #include browser-places.js
 #include browser-plugins.js
 #include browser-safebrowsing.js
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -792,16 +792,17 @@
                 <image id="webRTC-shareMicrophone-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-sharingMicrophone-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-shareScreen-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-sharingScreen-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="servicesInstall-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="translate-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="translated-notification-icon" class="notification-anchor-icon" role="button"/>
+                <image id="eme-notification-icon" class="notification-anchor-icon" role="button"/>
               </box>
               <!-- Use onclick instead of normal popup= syntax since the popup
                    code fires onmousedown, and hence eats our favicon drag events.
                    We only add the identity-box button to the tab order when the location bar
                    has focus, otherwise pressing F6 focuses it instead of the location bar -->
               <box id="identity-box" role="button"
                    align="center"
                    onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/ContentWebRTC.jsm");
+Cu.import("resource:///modules/ContentObservers.jsm");
 Cu.import("resource://gre/modules/InlineSpellChecker.jsm");
 Cu.import("resource://gre/modules/InlineSpellCheckerContent.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
   "resource:///modules/E10SUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
   "resource://gre/modules/BrowserUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ContentLinkHandler",
new file mode 100644
--- /dev/null
+++ b/browser/modules/ContentObservers.jsm
@@ -0,0 +1,47 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * This module is for small observers that we want to register once per content
+ * process, usually in order to forward content-based observer service notifications
+ * to the chrome process through message passing. Using a JSM avoids having them
+ * in content.js and thereby registering N observers for N open tabs, which is bad
+ * for perf.
+ */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = [];
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+let gEMEUIObserver = function(subject, topic, data) {
+  let win = subject.ownerDocument.defaultView.top;
+  let mm = getMessageManagerForWindow(win);
+  if (mm) {
+    mm.sendAsyncMessage("EMEVideo:MetadataLoaded", {
+      // bug 1129370 covers making this the actual DRM provider inferred from
+      // either |subject| or |data| here.
+      drmProvider: "Adobe"
+    });
+  }
+};
+
+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);
+  } catch(e if e.result == Cr.NS_NOINTERFACE) {
+    return null;
+  }
+}
+
+Services.obs.addObserver(gEMEUIObserver, "media-eme-metadataloaded", false);
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -10,16 +10,17 @@ XPCSHELL_TESTS_MANIFESTS += [
     'test/xpcshell/xpcshell.ini',
 ]
 
 EXTRA_JS_MODULES += [
     'BrowserUITelemetry.jsm',
     'CastingApps.jsm',
     'Chat.jsm',
     'ContentLinkHandler.jsm',
+    'ContentObservers.jsm',
     'ContentSearch.jsm',
     'ContentWebRTC.jsm',
     'CustomizationTabPreloader.jsm',
     'DirectoryLinksProvider.jsm',
     'E10SUtils.jsm',
     'Feeds.jsm',
     'FormSubmitObserver.jsm',
     'FormValidationHandler.jsm',
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -2168,16 +2168,27 @@ toolbarbutton.chevron > .toolbarbutton-i
   background-image: radial-gradient(circle farthest-corner at center 3px, rgb(233,242,252) 3%, rgba(172,206,255,0.75) 40%, rgba(87,151,201,0.5) 80%, transparent);
 }
 
 chatbox {
   border-top-left-radius: 2.5px;
   border-top-right-radius: 2.5px;
 }
 
+/* EME notifications */
+
+.popup-notification-icon[popupid="drmContentPlaying"],
+#eme-notification-icon {
+  list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
+}
+
+#eme-notification-icon:hover:active {
+  list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
+}
+
 /* Customization mode */
 
 %include ../shared/customizableui/customizeMode.inc.css
 
 #main-window[customize-entered] > #tab-view-deck {
   background-image: url("chrome://browser/skin/customizableui/customizeMode-gridTexture.png"),
                     linear-gradient(to bottom, #bcbcbc, #b5b5b5);
   background-attachment: fixed;
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -25,16 +25,17 @@ browser.jar:
   skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css
 * skin/classic/browser/devedition.css
 * skin/classic/browser/browser-lightweightTheme.css
   skin/classic/browser/click-to-play-warning-stripes.png
   skin/classic/browser/content-contextmenu.svg
   skin/classic/browser/dots.png                             (../shared/dots.png)
   skin/classic/browser/dots@2x.png                          (../shared/dots@2x.png)
+  skin/classic/browser/drm-icon.svg                         (../shared/drm-icon.svg)
 * skin/classic/browser/engineManager.css
   skin/classic/browser/fullscreen-darknoise.png
   skin/classic/browser/Geolocation-16.png
   skin/classic/browser/Geolocation-64.png
   skin/classic/browser/heartbeat-icon.svg                   (../shared/heartbeat-icon.svg)
   skin/classic/browser/heartbeat-star-lit.svg               (../shared/heartbeat-star-lit.svg)
   skin/classic/browser/heartbeat-star-off.svg               (../shared/heartbeat-star-off.svg)
   skin/classic/browser/identity.png
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -4574,16 +4574,27 @@ chatbox {
 
 window > chatbox {
   border-top-left-radius: @toolbarbuttonCornerRadius@;
   border-top-right-radius: @toolbarbuttonCornerRadius@;
   border-bottom-left-radius: @toolbarbuttonCornerRadius@;
   border-bottom-right-radius: @toolbarbuttonCornerRadius@;
 }
 
+/* EME notifications */
+
+.popup-notification-icon[popupid="drmContentPlaying"],
+#eme-notification-icon {
+  list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
+}
+
+#eme-notification-icon:hover:active {
+  list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
+}
+
 /* Customization mode */
 
 %include ../shared/customizableui/customizeMode.inc.css
 
 #main-window[customizing] {
   background-color: rgb(178,178,178);
 }
 
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -25,16 +25,17 @@ browser.jar:
   skin/classic/browser/actionicon-tab@2x.png
 * skin/classic/browser/browser.css                          (browser.css)
 * skin/classic/browser/devedition.css
 * skin/classic/browser/browser-lightweightTheme.css
   skin/classic/browser/click-to-play-warning-stripes.png
   skin/classic/browser/content-contextmenu.svg
   skin/classic/browser/dots.png                             (../shared/dots.png)
   skin/classic/browser/dots@2x.png                          (../shared/dots@2x.png)
+  skin/classic/browser/drm-icon.svg                         (../shared/drm-icon.svg)
 * skin/classic/browser/engineManager.css                    (engineManager.css)
   skin/classic/browser/fullscreen-darknoise.png
   skin/classic/browser/Geolocation-16.png
   skin/classic/browser/Geolocation-16@2x.png
   skin/classic/browser/Geolocation-64.png
   skin/classic/browser/Geolocation-64@2x.png
   skin/classic/browser/heartbeat-icon.svg                   (../shared/heartbeat-icon.svg)
   skin/classic/browser/heartbeat-star-lit.svg               (../shared/heartbeat-star-lit.svg)
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/drm-icon.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+     viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
+  <style>
+    #chains > use > path {
+      fill: url(#baseGradient);
+    }
+    #chains-pressed > use > path {
+      fill: url(#pressedGradient);
+    }
+
+    g:not(:target) {
+      display: none;
+    }
+  </style>
+  <defs>
+    <linearGradient id="baseGradient" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="16" y2="0">
+      <stop offset="0" style="stop-color:#808080"/>
+      <stop offset="1" style="stop-color:#999999"/>
+    </linearGradient>
+    <linearGradient id="pressedGradient" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="16" y2="0">
+      <stop offset="0" style="stop-color:#4D4D4D"/>
+      <stop offset="1" style="stop-color:#808080"/>
+    </linearGradient>
+    <path id="path1" d="M7.058,9.72c-0.245,0.245-0.62,0.27-0.834,0.056C6.01,9.562,6.035,9.186,6.28,8.942l0.218-0.218
+      c-0.245-0.245-0.645-0.245-0.89,0L4.496,9.836c-0.245,0.245-0.245,0.645,0,0.89l0.779,0.779c0.245,0.245,0.645,0.245,0.89,0
+      l1.112-1.112c0.245-0.245,0.245-0.645,0-0.89L7.058,9.72z"/>
+    <path id="path2" d="M10.726,4.496c-0.245-0.245-0.645-0.245-0.89,0L8.723,5.608c-0.245,0.245-0.245,0.645,0,0.89
+      L8.95,6.272c0.245-0.245,0.62-0.27,0.834-0.056s0.189,0.59-0.056,0.834L9.502,7.277c0.245,0.245,0.645,0.245,0.89,0l1.112-1.112
+      c0.245-0.245,0.245-0.645,0-0.89L10.726,4.496z"/>
+    <path id="path3" d="M8,0C3.582,0,0,3.582,0,8s3.582,8,8,8s8-3.582,8-8S12.418,0,8,0z M12.527,6.81l-1.489,1.489
+      c-0.631,0.631-1.663,0.631-2.293,0L8.612,8.167L8.167,8.612l0.133,0.133c0.631,0.631,0.631,1.663,0,2.293L6.81,12.527
+      c-0.631,0.631-1.663,0.631-2.293,0l-1.044-1.044c-0.631-0.631-0.631-1.663,0-2.293l1.489-1.489c0.631-0.631,1.663-0.631,2.293,0
+      l0.133,0.133l0.445-0.445L7.701,7.255c-0.631-0.631-0.631-1.663,0-2.293L9.19,3.473c0.631-0.631,1.663-0.631,2.293,0l1.044,1.044
+      C13.158,5.148,13.158,6.18,12.527,6.81z"/>
+  </defs>
+  <g id="chains">
+    <use xlink:href="#path1"/>
+    <use xlink:href="#path2"/>
+    <use xlink:href="#path3"/>
+  </g>
+  <g id="chains-pressed">
+    <use xlink:href="#path1"/>
+    <use xlink:href="#path2"/>
+    <use xlink:href="#path3"/>
+  </g>
+</svg>
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2791,16 +2791,27 @@ toolbarpaletteitem[place="palette"] > #s
   background-image: radial-gradient(circle farthest-corner at center 3px, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 40%, rgba(127,179,255,0.5) 80%, rgba(127,179,255,0.25));
 }
 
 chatbox {
   border-top-left-radius: 2.5px;
   border-top-right-radius: 2.5px;
 }
 
+/* EME notifications */
+
+.popup-notification-icon[popupid="drmContentPlaying"],
+#eme-notification-icon {
+  list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
+}
+
+#eme-notification-icon:hover:active {
+  list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
+}
+
 /* Customization mode */
 
 %include ../shared/customizableui/customizeMode.inc.css
 
 /**
  * This next rule is a hack to disable subpixel anti-aliasing on all
  * labels during the customize mode transition. Subpixel anti-aliasing
  * on Windows with Direct2D layers acceleration is particularly slow to
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -27,16 +27,17 @@ browser.jar:
         skin/classic/browser/actionicon-tab.png
 *       skin/classic/browser/browser.css
 *       skin/classic/browser/devedition.css
 *       skin/classic/browser/browser-lightweightTheme.css
         skin/classic/browser/click-to-play-warning-stripes.png
         skin/classic/browser/content-contextmenu.svg
         skin/classic/browser/dots.png                                (../shared/dots.png)
         skin/classic/browser/dots@2x.png                             (../shared/dots@2x.png)
+        skin/classic/browser/drm-icon.svg                            (../shared/drm-icon.svg)
 *       skin/classic/browser/engineManager.css
         skin/classic/browser/fullscreen-darknoise.png
         skin/classic/browser/Geolocation-16.png
         skin/classic/browser/Geolocation-64.png
         skin/classic/browser/heartbeat-icon.svg                      (../shared/heartbeat-icon.svg)
         skin/classic/browser/heartbeat-star-lit.svg                  (../shared/heartbeat-star-lit.svg)
         skin/classic/browser/heartbeat-star-off.svg                  (../shared/heartbeat-star-off.svg)
         skin/classic/browser/Info.png
@@ -483,16 +484,17 @@ browser.jar:
         skin/classic/aero/browser/actionicon-tab.png
 *       skin/classic/aero/browser/browser.css                        (browser-aero.css)
 *       skin/classic/aero/browser/devedition.css                     (devedition-aero.css)
 *       skin/classic/aero/browser/browser-lightweightTheme.css
         skin/classic/aero/browser/click-to-play-warning-stripes.png
 *       skin/classic/aero/browser/content-contextmenu.svg
         skin/classic/aero/browser/dots.png                           (../shared/dots.png)
         skin/classic/aero/browser/dots@2x.png                        (../shared/dots@2x.png)
+        skin/classic/aero/browser/drm-icon.svg                       (../shared/drm-icon.svg)
 *       skin/classic/aero/browser/engineManager.css
         skin/classic/aero/browser/fullscreen-darknoise.png
         skin/classic/aero/browser/Geolocation-16.png
         skin/classic/aero/browser/Geolocation-64.png
         skin/classic/aero/browser/heartbeat-icon.svg                 (../shared/heartbeat-icon.svg)
         skin/classic/aero/browser/heartbeat-star-lit.svg             (../shared/heartbeat-star-lit.svg)
         skin/classic/aero/browser/heartbeat-star-off.svg             (../shared/heartbeat-star-off.svg)
         skin/classic/aero/browser/Info.png                           (Info-aero.png)