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
--- 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();
-}