Bug 1071626 - make the global WebRTC sharing indicators actually list the streams with e10s enabled, r=felipe.
authorFlorian Quèze <florian@queze.net>
Wed, 01 Oct 2014 12:39:52 +0200
changeset 208167 7ee1bf648e8cd1ead74c2d0dc3aac1363534ccd7
parent 208166 6fa1218092a210b3ed51c1e43a5c33741d1ab067
child 208168 46db5df0e03f898aff35f46a0dba43bacd702bb4
push id27579
push userkwierso@gmail.com
push dateWed, 01 Oct 2014 23:02:13 +0000
treeherderautoland@f771fd927304 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs1071626
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1071626 - make the global WebRTC sharing indicators actually list the streams with e10s enabled, r=felipe.
browser/modules/ContentWebRTC.jsm
browser/modules/webrtcUI.jsm
--- a/browser/modules/ContentWebRTC.jsm
+++ b/browser/modules/ContentWebRTC.jsm
@@ -153,18 +153,29 @@ function updateIndicators() {
 
   let state = {
     showGlobalIndicator: count > 0,
     showCameraIndicator: false,
     showMicrophoneIndicator: false,
     showScreenSharingIndicator: ""
   };
 
+  let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
+               .getService(Ci.nsIMessageSender);
+  cpmm.sendAsyncMessage("webrtc:UpdatingIndicators");
+
+  // If several iframes in the same page use media streams, it's possible to
+  // have the same top level window several times. We use a Set to avoid
+  // sending duplicate notifications.
+  let contentWindows = new Set();
   for (let i = 0; i < count; ++i) {
-    let contentWindow = contentWindowSupportsArray.GetElementAt(i).top;
+    contentWindows.add(contentWindowSupportsArray.GetElementAt(i).top);
+  }
+
+  for (let contentWindow of contentWindows) {
     let camera = {}, microphone = {}, screen = {}, window = {}, app = {};
     MediaManagerService.mediaCaptureWindowState(contentWindow, camera,
                                                 microphone, screen, window, app);
     let tabState = {camera: camera.value, microphone: microphone.value};
     if (camera.value)
       state.showCameraIndicator = true;
     if (microphone.value)
       state.showMicrophoneIndicator = true;
@@ -184,18 +195,16 @@ function updateIndicators() {
     }
 
     tabState.windowId = getInnerWindowIDForWindow(contentWindow);
     tabState.documentURI = contentWindow.document.documentURI;
     let mm = getMessageManagerForWindow(contentWindow);
     mm.sendAsyncMessage("webrtc:UpdateBrowserIndicators", tabState);
   }
 
-  let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageSender);
   cpmm.sendAsyncMessage("webrtc:UpdateGlobalIndicators", state);
 }
 
 function removeBrowserSpecificIndicator(aSubject, aTopic, aData) {
   let contentWindow = Services.wm.getOuterWindowWithId(aData);
   let mm = getMessageManagerForWindow(contentWindow);
   if (mm)
     mm.sendAsyncMessage("webrtc:UpdateBrowserIndicators",
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -11,88 +11,68 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
                                   "resource://gre/modules/PluralForm.jsm");
 
-XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
-                                   "@mozilla.org/mediaManagerService;1",
-                                   "nsIMediaManagerService");
-
 this.webrtcUI = {
   init: function () {
     Services.obs.addObserver(maybeAddMenuIndicator, "browser-delayed-startup-finished", false);
 
     let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
                  .getService(Ci.nsIMessageBroadcaster);
+    ppmm.addMessageListener("webrtc:UpdatingIndicators", this);
     ppmm.addMessageListener("webrtc:UpdateGlobalIndicators", this);
 
     let mm = Cc["@mozilla.org/globalmessagemanager;1"]
                .getService(Ci.nsIMessageListenerManager);
     mm.addMessageListener("webrtc:Request", this);
     mm.addMessageListener("webrtc:UpdateBrowserIndicators", this);
   },
 
   uninit: function () {
     Services.obs.removeObserver(maybeAddMenuIndicator, "browser-delayed-startup-finished");
 
     let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
                  .getService(Ci.nsIMessageBroadcaster);
+    ppmm.removeMessageListener("webrtc:UpdatingIndicators", this);
     ppmm.removeMessageListener("webrtc:UpdateGlobalIndicators", this);
 
     let mm = Cc["@mozilla.org/globalmessagemanager;1"]
                .getService(Ci.nsIMessageListenerManager);
     mm.removeMessageListener("webrtc:Request", this);
     mm.removeMessageListener("webrtc:UpdateBrowserIndicators", this);
   },
 
   showGlobalIndicator: false,
   showCameraIndicator: false,
   showMicrophoneIndicator: false,
   showScreenSharingIndicator: "", // either "Application", "Screen" or "Window"
 
+  _streams: [],
   // The boolean parameters indicate which streams should be included in the result.
   getActiveStreams: function(aCamera, aMicrophone, aScreen) {
-    let contentWindowSupportsArray = MediaManagerService.activeMediaCaptureWindows;
-    let count = contentWindowSupportsArray.Count();
-    let activeStreams = [];
-    for (let i = 0; i < count; i++) {
-      let contentWindow = contentWindowSupportsArray.GetElementAt(i);
-
-      let info = {
-        Camera: {},
-        Microphone: {},
-        Window: {},
-        Screen: {},
-        Application: {}
-      };
-      MediaManagerService.mediaCaptureWindowState(contentWindow, info.Camera,
-                                                  info.Microphone, info.Screen,
-                                                  info.Window, info.Application);
-      if (!(aCamera && info.Camera.value ||
-            aMicrophone && info.Microphone.value ||
-            aScreen && (info.Screen.value || info.Window.value ||
-                        info.Application.value)))
-        continue;
-
-      let browser = getBrowserForWindow(contentWindow);
+    return webrtcUI._streams.filter(aStream => {
+      let state = aStream.state;
+      return aCamera && state.camera ||
+             aMicrophone && state.microphone ||
+             aScreen && state.screen;
+    }).map(aStream => {
+      let state = aStream.state;
+      let types = {camera: state.camera, microphone: state.microphone,
+                   screen: state.screen};
+      let browser = aStream.browser;
       let browserWindow = browser.ownerDocument.defaultView;
       let tab = browserWindow.gBrowser &&
-                browserWindow.gBrowser._getTabForContentWindow(contentWindow.top);
-      activeStreams.push({
-        uri: contentWindow.location.href,
-        tab: tab,
-        browser: browser,
-        types: info
-      });
-    }
-    return activeStreams;
+                browserWindow.gBrowser._getTabForBrowser(browser);
+      return {uri: state.documentURI, tab: tab, browser: browser, types: types};
+    });
   },
 
   showSharingDoorhanger: function(aActiveStream, aType) {
     let browserWindow = aActiveStream.browser.ownerDocument.defaultView;
     if (aActiveStream.tab) {
       browserWindow.gBrowser.selectedTab = aActiveStream.tab;
     } else {
       aActiveStream.browser.focus();
@@ -133,20 +113,24 @@ this.webrtcUI = {
     popupnotification.setAttribute("buttonlabel", bundle.getString(stringId));
   },
 
   receiveMessage: function(aMessage) {
     switch (aMessage.name) {
       case "webrtc:Request":
         prompt(aMessage.target, aMessage.data);
         break;
+      case "webrtc:UpdatingIndicators":
+        webrtcUI._streams = [];
+        break;
       case "webrtc:UpdateGlobalIndicators":
         updateIndicators(aMessage.data)
         break;
       case "webrtc:UpdateBrowserIndicators":
+        webrtcUI._streams.push({browser: aMessage.target, state: aMessage.data});
         updateBrowserSpecificIndicator(aMessage.target, aMessage.data);
         break;
     }
   }
 };
 
 function getBrowserForWindow(aContentWindow) {
   return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
@@ -557,26 +541,22 @@ function getGlobalIndicator() {
 #endif
 }
 
 function onTabSharingMenuPopupShowing(e) {
   let streams = webrtcUI.getActiveStreams(true, true, true);
   for (let streamInfo of streams) {
     let stringName = "getUserMedia.sharingMenu";
     let types = streamInfo.types;
-    if (types.Camera.value)
+    if (types.camera)
       stringName += "Camera";
-    if (types.Microphone.value)
+    if (types.microphone)
       stringName += "Microphone";
-    if (types.Screen.value)
-      stringName += "Screen";
-    else if (types.Application.value)
-      stringName += "Application";
-    else if (types.Window.value)
-      stringName += "Window";
+    if (types.screen)
+      stringName += types.screen;
 
     let doc = e.target.ownerDocument;
     let bundle = doc.defaultView.gNavigatorBundle;
 
     let origin;
     let uri;
     let href = streamInfo.uri;
     try {