Bug 1364975 - Allow WebExtensions to disable WebRTC, r?aswan
Implement privacy.network.peerConnectionEnabled to allow WebExtensions to enable and disable RTCPeerConnections (aka WebRTC).
MozReview-Commit-ID: 5zGotQNwsko
--- a/toolkit/components/extensions/ext-privacy.js
+++ b/toolkit/components/extensions/ext-privacy.js
@@ -55,16 +55,26 @@ ExtensionPreferencesManager.addSetting("
"network.http.speculative-parallel-limit": value ? undefined : 0,
"network.dns.disablePrefetch": !value,
"network.predictor.enabled": value,
"network.prefetch-next": value,
};
},
});
+ExtensionPreferencesManager.addSetting("network.peerConnectionEnabled", {
+ prefNames: [
+ "media.peerconnection.enabled",
+ ],
+
+ setCallback(value) {
+ return {[this.prefNames[0]]: value};
+ },
+});
+
ExtensionPreferencesManager.addSetting("network.webRTCIPHandlingPolicy", {
prefNames: [
"media.peerconnection.ice.default_address_only",
"media.peerconnection.ice.no_host",
"media.peerconnection.ice.proxy_only",
],
setCallback(value) {
@@ -114,16 +124,21 @@ this.privacy = class extends ExtensionAP
networkPredictionEnabled: getAPI(extension,
"network.networkPredictionEnabled",
() => {
return Preferences.get("network.predictor.enabled") &&
Preferences.get("network.prefetch-next") &&
Preferences.get("network.http.speculative-parallel-limit") > 0 &&
!Preferences.get("network.dns.disablePrefetch");
}),
+ peerConnectionEnabled: getAPI(extension,
+ "network.peerConnectionEnabled",
+ () => {
+ return Preferences.get("media.peerconnection.enabled");
+ }),
webRTCIPHandlingPolicy: getAPI(extension,
"network.webRTCIPHandlingPolicy",
() => {
if (Preferences.get("media.peerconnection.ice.proxy_only")) {
return "disable_non_proxied_udp";
}
let default_address_only =
--- a/toolkit/components/extensions/schemas/privacy.json
+++ b/toolkit/components/extensions/schemas/privacy.json
@@ -33,16 +33,20 @@
"description": "The IP handling policy of WebRTC."
}
],
"properties": {
"networkPredictionEnabled": {
"$ref": "types.Setting",
"description": "If enabled, the browser attempts to speed up your web browsing experience by pre-resolving DNS entries, prerendering sites (<code><link rel='prefetch' ...></code>), and preemptively opening TCP and SSL connections to servers. This preference's value is a boolean, defaulting to <code>true</code>."
},
+ "peerConnectionEnabled": {
+ "$ref": "types.Setting",
+ "description": "Allow users to enable and disable RTCPeerConnections (aka WebRTC)."
+ },
"webRTCIPHandlingPolicy": {
"$ref": "types.Setting",
"description": "Allow users to specify the media performance/privacy tradeoffs which impacts how WebRTC traffic will be routed and how much local address information is exposed. This preference's value is of type IPHandlingPolicy, defaulting to <code>default</code>."
}
}
},
{
"namespace": "privacy.websites",
--- a/toolkit/components/extensions/test/xpcshell/test_ext_privacy.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_privacy.js
@@ -209,94 +209,110 @@ add_task(async function test_privacy() {
for (let extension of testExtensions) {
await extension.unload();
}
await promiseShutdownManager();
});
-add_task(async function test_privacy_webRTCIPHandlingPolicy() {
- // Create a object to hold the default values of all the prefs.
- const PREF_DEFAULTS = {
- "media.peerconnection.ice.default_address_only": null,
- "media.peerconnection.ice.no_host": null,
- "media.peerconnection.ice.proxy_only": null,
+// This test can be used for any settings that are added which utilize only
+// boolean prefs.
+add_task(async function test_privacy_boolean_prefs() {
+ // Create an object to hold the values to which we will initialize the prefs.
+ const SETTINGS = {
+ "network.webRTCIPHandlingPolicy": {
+ "media.peerconnection.ice.default_address_only": false,
+ "media.peerconnection.ice.no_host": false,
+ "media.peerconnection.ice.proxy_only": false,
+ },
+ "network.peerConnectionEnabled": {
+ "media.peerconnection.enabled": true,
+ },
};
- // Store the default values of each pref.
- for (let pref in PREF_DEFAULTS) {
- PREF_DEFAULTS[pref] = ExtensionPreferencesManager.getDefaultValue(pref);
+ async function background() {
+ browser.test.onMessage.addListener(async (msg, ...args) => {
+ let data = args[0];
+ // The second argument is the end of the api name,
+ // e.g., "network.webRTCIPHandlingPolicy".
+ let apiObj = args[1].split(".").reduce((o, i) => o[i], browser.privacy);
+ let settingData;
+ switch (msg) {
+ case "set":
+ await apiObj.set(data);
+ settingData = await apiObj.get({});
+ browser.test.sendMessage("settingData", settingData);
+ break;
+
+ case "clear":
+ await apiObj.clear(data);
+ settingData = await apiObj.get({});
+ browser.test.sendMessage("settingData", settingData);
+ break;
+ }
+ });
+ }
+
+ // Set prefs to our initial values.
+ for (let setting in SETTINGS) {
+ for (let pref in SETTINGS[setting]) {
+ Preferences.set(pref, SETTINGS[setting][pref]);
+ }
}
do_register_cleanup(() => {
// Reset the prefs.
- for (let pref in PREF_DEFAULTS) {
- Preferences.reset(pref);
+ for (let setting in SETTINGS) {
+ for (let pref in SETTINGS[setting]) {
+ Preferences.reset(pref);
+ }
}
});
- async function background() {
- browser.test.onMessage.addListener(async (msg, value) => {
- let rtcData;
- switch (msg) {
- case "set":
- await browser.privacy.network.webRTCIPHandlingPolicy.set({value});
- rtcData = await browser.privacy.network.webRTCIPHandlingPolicy.get({});
- browser.test.sendMessage("rtcData", rtcData);
- break;
-
- case "clear":
- await browser.privacy.network.webRTCIPHandlingPolicy.clear({});
- rtcData = await browser.privacy.network.webRTCIPHandlingPolicy.get({});
- browser.test.sendMessage("rtcData", rtcData);
- break;
-
- }
- });
- }
-
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["privacy"],
},
useAddonManager: "temporary",
});
await promiseStartupManager();
await extension.startup();
- async function testSetting(value, truePrefs) {
- extension.sendMessage("set", value);
- let data = await extension.awaitMessage("rtcData");
+ async function testSetting(setting, value, truePrefs) {
+ extension.sendMessage("set", {value: value}, setting);
+ let data = await extension.awaitMessage("settingData");
equal(data.value, value);
- for (let pref in PREF_DEFAULTS) {
+ for (let pref in SETTINGS[setting]) {
let prefValue = Preferences.get(pref);
- if (truePrefs.includes(pref)) {
- ok(prefValue, `${pref} set correctly for ${value}`);
- } else {
- equal(prefValue, PREF_DEFAULTS[pref], `${pref} contains default value for ${value}`);
- }
+ equal(prefValue, truePrefs.includes(pref), `${pref} set correctly for ${value}`);
}
}
await testSetting(
+ "network.webRTCIPHandlingPolicy",
"default_public_and_private_interfaces",
["media.peerconnection.ice.default_address_only"]);
await testSetting(
+ "network.webRTCIPHandlingPolicy",
"default_public_interface_only",
["media.peerconnection.ice.default_address_only", "media.peerconnection.ice.no_host"]);
await testSetting(
+ "network.webRTCIPHandlingPolicy",
"disable_non_proxied_udp",
["media.peerconnection.ice.proxy_only"]);
- await testSetting("default", []);
+ await testSetting("network.webRTCIPHandlingPolicy", "default", []);
+
+ await testSetting("network.peerConnectionEnabled", false, []);
+ await testSetting("network.peerConnectionEnabled", true, ["media.peerconnection.enabled"]);
await extension.unload();
await promiseShutdownManager();
});
add_task(async function test_exceptions() {
async function background() {