Bug 1458020 - 4. Add camera permission in the parent process; r?snorp
We had a permission error because we were trying to add camera
permission in the child process. Move it to the parent process, where
the permission is actually checked.
MozReview-Commit-ID: 2OE3BznlVTD
--- a/mobile/android/components/geckoview/GeckoViewPermission.js
+++ b/mobile/android/components/geckoview/GeckoViewPermission.js
@@ -41,16 +41,36 @@ GeckoViewPermission.prototype = {
}
case "PeerConnection:request": {
this.handlePeerConnectionRequest(aSubject);
break;
}
}
},
+ receiveMessage(aMsg) {
+ switch (aMsg.name) {
+ case "GeckoView:AddCameraPermission": {
+ let uri;
+ try {
+ // This fails for principals that serialize to "null", e.g. file URIs.
+ uri = Services.io.newURI(aMsg.data.origin);
+ } catch (e) {
+ uri = Services.io.newURI(aMsg.data.documentURI);
+ }
+ // Although the lifetime is "session" it will be removed upon
+ // use so it's more of a one-shot.
+ Services.perms.add(uri, "MediaManagerVideo",
+ Services.perms.ALLOW_ACTION,
+ Services.perms.EXPIRE_SESSION);
+ break;
+ }
+ }
+ },
+
handleMediaAskDevicePermission: function(aType, aCallback) {
let perms = [];
if (aType === "video" || aType === "all") {
perms.push(PERM_CAMERA);
}
if (aType === "audio" || aType === "all") {
perms.push(PERM_RECORD_AUDIO);
}
@@ -117,21 +137,20 @@ GeckoViewPermission.prototype = {
return;
}
let allowedDevices = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
if (constraints.video) {
let video = devices.find(device => response.video === device.id);
if (!video) {
throw new Error("invalid video id");
}
- // Although the lifetime is "session" it will be removed upon
- // use so it's more of a one-shot.
- Services.perms.add(uri, "MediaManagerVideo",
- Services.perms.ALLOW_ACTION,
- Services.perms.EXPIRE_SESSION);
+ Services.cpmm.sendAsyncMessage("GeckoView:AddCameraPermission", {
+ origin: win.origin,
+ documentURI: win.document.documentURI,
+ });
allowedDevices.appendElement(video);
}
if (constraints.audio) {
let audio = devices.find(device => response.audio === device.id);
if (!audio) {
throw new Error("invalid audio id");
}
allowedDevices.appendElement(audio);
--- a/mobile/android/components/geckoview/GeckoViewStartup.js
+++ b/mobile/android/components/geckoview/GeckoViewStartup.js
@@ -41,16 +41,19 @@ GeckoViewStartup.prototype = {
// Parent and content process.
GeckoViewUtils.addLazyGetter(this, "GeckoViewPermission", {
service: "@mozilla.org/content-permission/prompt;1",
observers: [
"getUserMedia:ask-device-permission",
"getUserMedia:request",
"PeerConnection:request",
],
+ ppmm: [
+ "GeckoView:AddCameraPermission",
+ ],
});
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
// Parent process only.
this.setResourceSubstitutions();
Services.mm.loadFrameScript(
"chrome://geckoview/content/GeckoViewPromptContent.js", true);
--- a/mobile/android/modules/geckoview/GeckoViewUtils.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewUtils.jsm
@@ -63,16 +63,21 @@ var GeckoViewUtils = {
if (!once) {
Services.obs.addObserver(scope[name], topic);
}
scope[name].observe(subject, topic, data); // Explicitly notify new observer
};
observers.forEach(topic => Services.obs.addObserver(observer, topic));
}
+ if (!this.IS_PARENT_PROCESS) {
+ // ppmm, mm, and ged are only available in the parent process.
+ return;
+ }
+
let addMMListener = (target, names) => {
let listener = msg => {
target.removeMessageListener(msg.name, listener);
if (!once) {
target.addMessageListener(msg.name, scope[name]);
}
scope[name].receiveMessage(msg);
};