Bug 1352522, part 1 - Add ContentWebRTC observers in ContentObservers.js. r=florian draft
authorAndrew McCreight <continuation@gmail.com>
Fri, 07 Apr 2017 08:48:58 -0700
changeset 558678 c048c9d8ce0cc123b5ead2a6deae27ba154e4992
parent 558677 ed7b4fdc6616a9b2679c7b3a22bd71eeb3cadde3
child 558679 364b1e25000ebc7590f776966d56ea02ea9301a2
push id52931
push userbmo:continuation@gmail.com
push dateFri, 07 Apr 2017 22:06:59 +0000
reviewersflorian
bugs1352522
milestone55.0a1
Bug 1352522, part 1 - Add ContentWebRTC observers in ContentObservers.js. r=florian This avoids importing ContentWebRTC.jsm just to register observers that may never observe anything. Avoiding importing .jsms reduces memory usage. ContentObserver.js gets loaded once per content process, so I think the ._initialized stuff is not needed in the process script. MozReview-Commit-ID: 5r9L3bfFS0U
browser/base/content/content.js
browser/modules/ContentObservers.js
browser/modules/ContentWebRTC.jsm
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -7,27 +7,28 @@
  * depend on the frame being contained in tabbrowser. */
 
 /* eslint-env mozilla/frame-script */
 
 var {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://gre/modules/InlineSpellChecker.jsm");
 Cu.import("resource://gre/modules/InlineSpellCheckerContent.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
   "resource:///modules/E10SUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
   "resource://gre/modules/BrowserUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ContentLinkHandler",
   "resource:///modules/ContentLinkHandler.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ContentWebRTC",
+  "resource:///modules/ContentWebRTC.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent",
   "resource://gre/modules/LoginManagerContent.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LoginFormFactory",
   "resource://gre/modules/LoginManagerContent.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils",
   "resource://gre/modules/InsecurePasswordUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PluginContent",
   "resource:///modules/PluginContent.jsm");
@@ -697,17 +698,16 @@ ContentLinkHandler.init(this);
 
 // TODO: Load this lazily so the JSM is run only if a relevant event/message fires.
 var pluginContent = new PluginContent(global);
 
 addEventListener("DOMWindowFocus", function(event) {
   sendAsyncMessage("DOMWindowFocus", {});
 }, false);
 
-ContentWebRTC.init();
 addMessageListener("rtcpeer:Allow", ContentWebRTC);
 addMessageListener("rtcpeer:Deny", ContentWebRTC);
 addMessageListener("webrtc:Allow", ContentWebRTC);
 addMessageListener("webrtc:Deny", ContentWebRTC);
 addMessageListener("webrtc:StopSharing", ContentWebRTC);
 addMessageListener("webrtc:StartBrowserSharing", () => {
   let windowID = content.QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
--- a/browser/modules/ContentObservers.js
+++ b/browser/modules/ContentObservers.js
@@ -12,16 +12,20 @@
  * which is bad for perf.
  */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "ContentWebRTC",
+  "resource:///modules/ContentWebRTC.jsm");
 
 var gEMEUIObserver = function(subject, topic, data) {
   let win = subject.top;
   let mm = getMessageManagerForWindow(win);
   if (mm) {
     mm.sendAsyncMessage("EMEVideo:ContentMediaKeysRequest", data);
   }
 };
@@ -47,8 +51,34 @@ function getMessageManagerForWindow(aCon
       return null;
     }
     throw e;
   }
 }
 
 Services.obs.addObserver(gEMEUIObserver, "mediakeys-request", false);
 Services.obs.addObserver(gDecoderDoctorObserver, "decoder-doctor-notification", false);
+
+
+// ContentWebRTC observer registration.
+const kWebRTCObserverTopics = ["getUserMedia:request",
+                               "recording-device-stopped",
+                               "PeerConnection:request",
+                               "recording-device-events",
+                               "recording-window-ended"];
+
+function webRTCObserve(aSubject, aTopic, aData) {
+  ContentWebRTC.observe(aSubject, aTopic, aData);
+}
+
+for (let topic of kWebRTCObserverTopics) {
+  Services.obs.addObserver(webRTCObserve, topic, false);
+}
+
+if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT)
+  Services.obs.addObserver(processShutdown, "content-child-shutdown", false);
+
+function processShutdown() {
+  for (let topic of kWebRTCObserverTopics) {
+    Services.obs.removeObserver(webRTCObserve, topic);
+  }
+  Services.obs.removeObserver(processShutdown, "content-child-shutdown");
+}
--- a/browser/modules/ContentWebRTC.jsm
+++ b/browser/modules/ContentWebRTC.jsm
@@ -12,58 +12,50 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
                                    "@mozilla.org/mediaManagerService;1",
                                    "nsIMediaManagerService");
 
 const kBrowserURL = "chrome://browser/content/browser.xul";
 
 this.ContentWebRTC = {
-  _initialized: false,
-
-  init() {
-    if (this._initialized)
-      return;
-
-    this._initialized = true;
-    Services.obs.addObserver(handleGUMRequest, "getUserMedia:request", false);
-    Services.obs.addObserver(handleGUMStop, "recording-device-stopped", false);
-    Services.obs.addObserver(handlePCRequest, "PeerConnection:request", false);
-    Services.obs.addObserver(updateIndicators, "recording-device-events", false);
-    Services.obs.addObserver(removeBrowserSpecificIndicator, "recording-window-ended", false);
-
-    if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT)
-      Services.obs.addObserver(processShutdown, "content-child-shutdown", false);
-  },
-
-  uninit() {
-    Services.obs.removeObserver(handleGUMRequest, "getUserMedia:request");
-    Services.obs.removeObserver(handleGUMStop, "recording-device-stopped");
-    Services.obs.removeObserver(handlePCRequest, "PeerConnection:request");
-    Services.obs.removeObserver(updateIndicators, "recording-device-events");
-    Services.obs.removeObserver(removeBrowserSpecificIndicator, "recording-window-ended");
-
-    if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT)
-      Services.obs.removeObserver(processShutdown, "content-child-shutdown");
-
-    this._initialized = false;
-  },
-
   // Called only for 'unload' to remove pending gUM prompts in reloaded frames.
   handleEvent(aEvent) {
     let contentWindow = aEvent.target.defaultView;
     let mm = getMessageManagerForWindow(contentWindow);
     for (let key of contentWindow.pendingGetUserMediaRequests.keys()) {
       mm.sendAsyncMessage("webrtc:CancelRequest", key);
     }
     for (let key of contentWindow.pendingPeerConnectionRequests.keys()) {
       mm.sendAsyncMessage("rtcpeer:CancelRequest", key);
     }
   },
 
+  // This observer is registered in ContentObservers.js to avoid
+  // loading this .jsm when WebRTC is not in use.
+  observe(aSubject, aTopic, aData) {
+    switch (aTopic) {
+      case "getUserMedia:request":
+	handleGUMRequest(aSubject, aTopic, aData);
+	break;
+      case "recording-device-stopped":
+	handleGUMStop(aSubject, aTopic, aData);
+	break;
+      case "PeerConnection:request":
+	handlePCRequest(aSubject, aTopic, aData);
+	break;
+      case "recording-device-events":
+	updateIndicators(aSubject, aTopic, aData);
+	break;
+      case "recording-window-ended":
+	removeBrowserSpecificIndicator(aSubject, aTopic, aData);
+	break;
+    }
+  },
+
   receiveMessage(aMessage) {
     switch (aMessage.name) {
       case "rtcpeer:Allow":
       case "rtcpeer:Deny": {
         let callID = aMessage.data.callID;
         let contentWindow = Services.wm.getOuterWindowWithId(aMessage.data.windowID);
         forgetPCRequest(contentWindow, callID);
         let topic = (aMessage.name == "rtcpeer:Allow") ? "PeerConnection:response:allow" :
@@ -405,12 +397,8 @@ function getMessageManagerForWindow(aCon
     return ir.getInterface(Ci.nsIContentFrameMessageManager);
   } catch (e) {
     if (e.result == Cr.NS_NOINTERFACE) {
       return null;
     }
     throw e;
   }
 }
-
-function processShutdown() {
-  ContentWebRTC.uninit();
-}