Bug 1388724 - 6. Make WebrtcUI not depend on browser.js; r=esawin
Move WebrtcUI loading from browser.js to BrowserCLH.js, so that it can
be loaded without GeckoApp/browser.js being active. Also use the
universal doorhanger API to show the prompts.
MozReview-Commit-ID: Gqsthvn7ZXA
--- a/mobile/android/chrome/content/WebrtcUI.js
+++ b/mobile/android/chrome/content/WebrtcUI.js
@@ -1,19 +1,23 @@
/* 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/. */
"use strict";
this.EXPORTED_SYMBOLS = ["WebrtcUI"];
+XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService", "@mozilla.org/mediaManagerService;1", "nsIMediaManagerService");
XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "ParentalControls", "@mozilla.org/parental-controls-service;1", "nsIParentalControlsService");
XPCOMUtils.defineLazyModuleGetter(this, "RuntimePermissions", "resource://gre/modules/RuntimePermissions.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "DoorHanger",
+ "resource://gre/modules/Prompt.jsm");
+
var WebrtcUI = {
_notificationId: null,
// Add-ons can override stock permission behavior by doing:
//
// var stockObserve = WebrtcUI.observe;
//
// webrtcUI.observe = function(aSubject, aTopic, aData) {
@@ -128,17 +132,17 @@ var WebrtcUI = {
let constraints = aSubject.getConstraints();
let contentWindow = Services.wm.getOuterWindowWithId(aSubject.windowID);
contentWindow.navigator.mozGetUserMediaDevices(
constraints,
function(devices) {
if (!ParentalControls.isAllowed(ParentalControls.CAMERA_MICROPHONE)) {
Services.obs.notifyObservers(null, "getUserMedia:response:deny", aSubject.callID);
- WebrtcUI.showBlockMessage(devices);
+ WebrtcUI.showBlockMessage(contentWindow, devices);
return;
}
WebrtcUI.prompt(contentWindow, aSubject.callID, constraints.audio,
constraints.video, devices);
},
function(error) {
Cu.reportError(error);
@@ -238,17 +242,17 @@ var WebrtcUI = {
label: Strings.browser.GetStringFromName("getUserMedia." + aType + ".prompt"),
values: list
});
}
}
},
- showBlockMessage: function(aDevices) {
+ showBlockMessage: function(aWindow, aDevices) {
let microphone = false;
let camera = false;
for (let device of aDevices) {
device = device.QueryInterface(Ci.nsIMediaDevice);
if (device.type == "audio") {
microphone = true;
} else if (device.type == "video") {
@@ -260,17 +264,28 @@ var WebrtcUI = {
if (microphone && !camera) {
message = Strings.browser.GetStringFromName("getUserMedia.blockedMicrophoneAccess");
} else if (camera && !microphone) {
message = Strings.browser.GetStringFromName("getUserMedia.blockedCameraAccess");
} else {
message = Strings.browser.GetStringFromName("getUserMedia.blockedCameraAndMicrophoneAccess");
}
- NativeWindow.doorhanger.show(message, "webrtc-blocked", [], BrowserApp.selectedTab.id, {});
+ DoorHanger.show(aWindow, message, "webrtc-blocked");
+ },
+
+ getChromeWindow: function getChromeWindow(aWindow) {
+ let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .QueryInterface(Ci.nsIDOMChromeWindow);
+ return chromeWin;
},
prompt: function prompt(aContentWindow, aCallID, aAudioRequested,
aVideoRequested, aDevices) {
let audioDevices = [];
let videoDevices = [];
for (let device of aDevices) {
device = device.QueryInterface(Ci.nsIMediaDevice);
@@ -291,28 +306,30 @@ var WebrtcUI = {
requestType = "CameraAndMicrophone";
else if (audioDevices.length)
requestType = "Microphone";
else if (videoDevices.length)
requestType = "Camera";
else
return;
+ let chromeWin = this.getChromeWindow(aContentWindow);
let uri = aContentWindow.document.documentURIObject;
let host = uri.host;
- let requestor = BrowserApp.manifest ? "'" + BrowserApp.manifest.name + "'" : host;
+ let requestor = (chromeWin.BrowserApp && chromeWin.BrowserApp.manifest) ?
+ "'" + BrowserApp.manifest.name + "'" : host;
let message = Strings.browser.formatStringFromName("getUserMedia.share" + requestType + ".message", [ requestor ], 1);
let options = { inputs: [] };
if (videoDevices.length > 1 || audioDevices.length > 0) {
// videoSource is both the string used for l10n lookup and the object that will be returned
this._addDevicesToOptions(videoDevices, "videoSource", options);
}
if (audioDevices.length > 1 || videoDevices.length > 0) {
this._addDevicesToOptions(audioDevices, "audioDevice", options);
}
let buttons = this.getDeviceButtons(audioDevices, videoDevices, aCallID, uri);
- NativeWindow.doorhanger.show(message, "webrtc-request", buttons, BrowserApp.selectedTab.id, options, "WEBRTC");
+ DoorHanger.show(aContentWindow, message, "webrtc-request", buttons, options, "WEBRTC");
}
}
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -148,26 +148,16 @@ lazilyLoadedBrowserScripts.forEach(funct
});
});
var lazilyLoadedObserverScripts = [
["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"],
["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"],
];
-if (AppConstants.MOZ_WEBRTC) {
- lazilyLoadedObserverScripts.push(
- ["WebrtcUI", ["getUserMedia:ask-device-permission",
- "getUserMedia:request",
- "PeerConnection:request",
- "recording-device-events",
- "VideoCapture:Paused",
- "VideoCapture:Resumed"], "chrome://browser/content/WebrtcUI.js"])
-}
-
lazilyLoadedObserverScripts.forEach(function (aScript) {
let [name, notifications, script] = aScript;
XPCOMUtils.defineLazyGetter(window, name, function() {
let sandbox = {};
Services.scriptloader.loadSubScript(script, sandbox);
return sandbox[name];
});
let observer = (s, t, d) => {
@@ -278,21 +268,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
"@mozilla.org/parental-controls-service;1", "nsIParentalControlsService");
XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils",
"@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
XPCOMUtils.defineLazyServiceGetter(window, "URIFixup",
"@mozilla.org/docshell/urifixup;1", "nsIURIFixup");
-if (AppConstants.MOZ_WEBRTC) {
- XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
- "@mozilla.org/mediaManagerService;1", "nsIMediaManagerService");
-}
-
XPCOMUtils.defineLazyModuleGetter(this, "Log",
"resource://gre/modules/AndroidLog.jsm", "AndroidLog");
// Define the "dump" function as a binding of the Log.d function so it specifies
// the "debug" priority and a log tag.
function dump(msg) {
Log.d("Browser", msg);
}
--- a/mobile/android/components/BrowserCLH.js
+++ b/mobile/android/components/BrowserCLH.js
@@ -4,16 +4,28 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+ "resource://gre/modules/AppConstants.jsm");
+
+var Strings = {};
+
+XPCOMUtils.defineLazyGetter(Strings, "brand", _ =>
+ Services.strings.createBundle("chrome://branding/locale/brand.properties"));
+XPCOMUtils.defineLazyGetter(Strings, "browser", _ =>
+ Services.strings.createBundle("chrome://browser/locale/browser.properties"));
+XPCOMUtils.defineLazyGetter(Strings, "reader", _ =>
+ Services.strings.createBundle("chrome://global/locale/aboutReader.properties"));
+
function BrowserCLH() {}
BrowserCLH.prototype = {
/**
* Register resource://android as the APK root.
*
* Consumers can access Android assets using resource://android/assets/FILENAME.
*/
@@ -23,20 +35,52 @@ BrowserCLH.prototype = {
let url = registry.convertChromeURL(Services.io.newURI("chrome://browser/content/aboutHome.xhtml")).spec;
// Like jar:file:///data/app/org.mozilla.fennec-2.apk!/
url = url.substring(4, url.indexOf("!/") + 2);
let protocolHandler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
protocolHandler.setSubstitution("android", Services.io.newURI(url));
},
+ addObserverScripts: function(aScripts) {
+ aScripts.forEach(item => {
+ let [name, notifications, script] = item;
+ XPCOMUtils.defineLazyGetter(this, name, _ => {
+ let sandbox = {};
+ Services.scriptloader.loadSubScript(script, sandbox);
+ return sandbox[name];
+ });
+ let observer = (subject, topic, data) => {
+ Services.obs.removeObserver(observer, topic);
+ Services.obs.addObserver(this[name], topic);
+ this[name].observe(subject, topic, data); // Explicitly notify new observer
+ };
+ notifications.forEach(notification => {
+ Services.obs.addObserver(observer, notification);
+ });
+ });
+ },
+
observe: function(subject, topic, data) {
switch (topic) {
case "app-startup":
this.setResourceSubstitutions();
+
+ let observerScripts = [];
+ if (AppConstants.MOZ_WEBRTC) {
+ observerScripts.push(["WebrtcUI", [
+ "getUserMedia:ask-device-permission",
+ "getUserMedia:request",
+ "PeerConnection:request",
+ "recording-device-events",
+ "VideoCapture:Paused",
+ "VideoCapture:Resumed",
+ ], "chrome://browser/content/WebrtcUI.js"]);
+ }
+ this.addObserverScripts(observerScripts);
break;
}
},
// QI
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
// XPCOMUtils factory