Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit d492662

Browse files
committed
Bug 1591755 - Support Web Permissions in FxR for Desktop r=Gijs,pbz
This change will be the first of multiple changes to control permissions in FxR on PC. This change introduces a new class, FxrPermissionPromptPrototype, in the FxR front end code. With the introduction of this class, all permission requests are denied by default. Subsequent changes will provide UI to give user control. Differential Revision: https://phabricator.services.mozilla.com/D52283 --HG-- extra : moz-landing-system : lando
1 parent a71564b commit d492662

6 files changed

Lines changed: 200 additions & 1 deletion

File tree

browser/components/BrowserGlue.jsm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4105,6 +4105,14 @@ ContentPermissionPrompt.prototype = {
41054105
* The request that we're to show a prompt for.
41064106
*/
41074107
prompt(request) {
4108+
if (request.element && request.element.fxrPermissionPrompt) {
4109+
// For Firefox Reality on Desktop, switch to a different mechanism to
4110+
// prompt the user since fewer permissions are available and since many
4111+
// UI dependencies are not availabe.
4112+
request.element.fxrPermissionPrompt(request);
4113+
return;
4114+
}
4115+
41084116
let type;
41094117
try {
41104118
// Only allow exactly one permission request here.

browser/fxr/content/fxrui.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<link rel="stylesheet" href="fxrui.css" />
1616
<link rel="stylesheet" href="fxrui_blue.css" />
1717
<script src="common.js"></script>
18+
<script src="permissions.js"></script>
1819
<script src="fxrui.js"></script>
1920
</head>
2021

browser/fxr/content/fxrui.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
55

66
/* import-globals-from common.js */
7+
/* import-globals-from permissions.js */
78

89
// Configuration vars
910
let homeURL = "https://webxr.today/";
@@ -15,6 +16,12 @@ let licenseURL =
1516

1617
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/browser
1718
let browser = null;
19+
// Keep track of the current Permissions request to only allow one outstanding
20+
// request/prompt at a time.
21+
let currentPermissionRequest = null;
22+
// And, keep a queue of pending Permissions requests to resolve when the
23+
// current request finishes
24+
let pendingPermissionRequests = [];
1825
// The following variable map to UI elements whose behavior changes depending
1926
// on some state from the browser control
2027
let urlInput = null;
@@ -79,6 +86,10 @@ function setupBrowser() {
7986
this.loadURI(url, { triggeringPrincipal: gSystemPrincipal });
8087
};
8188

89+
// Expose this function for Permissions to be used on this browser element
90+
// in other parts of the frontend
91+
browser.fxrPermissionPrompt = permissionPrompt;
92+
8293
urlInput.value = homeURL;
8394
browser.loadUrlWithSystemPrincipal(homeURL);
8495

@@ -203,6 +214,10 @@ function setupUrlBar() {
203214
});
204215
}
205216

217+
//
218+
// Code to manage Settings UI
219+
//
220+
206221
function openSettings() {
207222
let browserSettingsUI = document.createXULElement("browser");
208223
browserSettingsUI.setAttribute("type", "chrome");
@@ -233,3 +248,35 @@ function showReportIssue() {
233248
closeSettings();
234249
browser.loadUrlWithSystemPrincipal(reportIssueURL);
235250
}
251+
252+
//
253+
// Code to manage Permissions UI
254+
//
255+
256+
function permissionPrompt(aRequest) {
257+
let newPrompt;
258+
if (aRequest instanceof Ci.nsIContentPermissionRequest) {
259+
newPrompt = new FxrContentPrompt(aRequest, this, finishPrompt);
260+
} else {
261+
newPrompt = new FxrWebRTCPrompt(aRequest, this, finishPrompt);
262+
}
263+
264+
if (currentPermissionRequest) {
265+
// There is already an outstanding request running. Cache this new request
266+
// to be prompted later
267+
pendingPermissionRequests.push(newPrompt);
268+
} else {
269+
currentPermissionRequest = newPrompt;
270+
currentPermissionRequest.showPrompt();
271+
}
272+
}
273+
274+
function finishPrompt() {
275+
if (pendingPermissionRequests.length) {
276+
// Prompt the next request
277+
currentPermissionRequest = pendingPermissionRequests.shift();
278+
currentPermissionRequest.showPrompt();
279+
} else {
280+
currentPermissionRequest = null;
281+
}
282+
}

browser/fxr/content/permissions.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
/* import-globals-from fxrui.js */
7+
8+
/**
9+
* Code to manage Permissions UI
10+
*
11+
* FxR on Desktop only supports granting permission for
12+
* - Location
13+
* - Camera
14+
* - Microphone
15+
* Any other permissions are automatically denied.
16+
*
17+
*/
18+
19+
// Base class for managing permissions in FxR on PC
20+
class FxrPermissionPromptPrototype {
21+
constructor(aRequest, aBrowser, aCallback) {
22+
this.request = aRequest;
23+
this.targetBrowser = aBrowser;
24+
this.responseCallback = aCallback;
25+
}
26+
27+
showPrompt() {
28+
// For now, all permissions default to denied. Testing for allow must be
29+
// done manually until UI is finished:
30+
// Bug 1594840 - Add UI for Web Permissions in FxR for Desktop
31+
this.defaultDeny();
32+
}
33+
34+
defaultDeny() {
35+
this.handleResponse(false);
36+
}
37+
38+
handleResponse(allowed) {
39+
if (allowed) {
40+
this.allow();
41+
} else {
42+
this.deny();
43+
}
44+
45+
this.responseCallback();
46+
}
47+
}
48+
49+
// WebRTC-specific class implementation
50+
class FxrWebRTCPrompt extends FxrPermissionPromptPrototype {
51+
showPrompt() {
52+
for (let typeName of this.request.requestTypes) {
53+
if (typeName !== "Microphone" && typeName !== "Camera") {
54+
// Only Microphone and Camera requests are allowed. Automatically deny
55+
// any other request.
56+
this.defaultDeny();
57+
return;
58+
}
59+
}
60+
61+
super.showPrompt();
62+
}
63+
64+
allow() {
65+
let { audioDevices, videoDevices } = this.request;
66+
67+
let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
68+
this.request.origin
69+
);
70+
71+
// For now, collect the first audio and video device by default. User
72+
// selection will be enabled later:
73+
// Bug 1594841 - Add UI to select device for WebRTC in FxR for Desktop
74+
let allowedDevices = [];
75+
76+
if (audioDevices.length) {
77+
allowedDevices.push(audioDevices[0].deviceIndex);
78+
}
79+
80+
if (videoDevices.length) {
81+
Services.perms.addFromPrincipal(
82+
principal,
83+
"MediaManagerVideo",
84+
Services.perms.ALLOW_ACTION,
85+
Services.perms.EXPIRE_SESSION
86+
);
87+
allowedDevices.push(videoDevices[0].deviceIndex);
88+
}
89+
90+
this.targetBrowser.messageManager.sendAsyncMessage("webrtc:Allow", {
91+
callID: this.request.callID,
92+
windowID: this.request.windowID,
93+
devices: allowedDevices,
94+
});
95+
}
96+
97+
deny() {
98+
this.targetBrowser.messageManager.sendAsyncMessage("webrtc:Deny", {
99+
callID: this.request.callID,
100+
windowID: this.request.windowID,
101+
});
102+
}
103+
}
104+
105+
// Implementation for other, non-WebRTC web permission prompts
106+
class FxrContentPrompt extends FxrPermissionPromptPrototype {
107+
showPrompt() {
108+
// Only allow exactly one permission request here.
109+
let types = this.request.types.QueryInterface(Ci.nsIArray);
110+
if (types.length != 1) {
111+
this.defaultDeny();
112+
return;
113+
}
114+
115+
// Only Location is supported from this type of request
116+
let type = types.queryElementAt(0, Ci.nsIContentPermissionType).type;
117+
if (type !== "geolocation") {
118+
this.defaultDeny();
119+
return;
120+
}
121+
122+
// Override type so that it can be more easily interpreted by the code
123+
// for the prompt.
124+
type = "Location";
125+
super.showPrompt();
126+
}
127+
128+
allow() {
129+
this.request.allow();
130+
}
131+
132+
deny() {
133+
this.request.cancel();
134+
}
135+
}

browser/fxr/jar.mn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ browser.jar:
1212
content/browser/fxr/fxrui_blue.css (content/fxrui_blue.css)
1313
content/browser/fxr/fxrui.js (content/fxrui.js)
1414
content/browser/fxr/fxr-fullScreen.js (content/fxr-fullScreen.js)
15+
content/browser/fxr/permissions.js (content/permissions.js)
1516
content/browser/fxr/prefs.html (content/prefs.html)
1617
content/browser/fxr/prefs.css (content/prefs.css)
1718
content/browser/fxr/prefs.js (content/prefs.js)

browser/modules/webrtcUI.jsm

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,14 @@ var webrtcUI = {
298298
break;
299299
}
300300
case "webrtc:Request":
301-
prompt(aMessage.target, aMessage.data);
301+
if (aMessage.target.fxrPermissionPrompt) {
302+
// For Firefox Reality on Desktop, switch to a different mechanism to
303+
// prompt the user since fewer permissions are available and since many
304+
// UI dependencies are not availabe.
305+
aMessage.target.fxrPermissionPrompt(aMessage.data);
306+
} else {
307+
prompt(aMessage.target, aMessage.data);
308+
}
302309
break;
303310
case "webrtc:StopRecording":
304311
stopRecording(aMessage.target, aMessage.data);

0 commit comments

Comments
 (0)