Bug 1364975 - Allow WebExtensions to disable WebRTC, r=aswan
authorBob Silverberg <bsilverberg@mozilla.com>
Wed, 24 May 2017 09:58:43 -0400
changeset 361778 e62d60b214d1d68a604fb7a65b01a5a6691743b2
parent 361777 4db765715213ac3e0bf46fe492acb5b031b128e7
child 361779 3ad1b460540d2a6eda0011805457d9701d113f26
push id31942
push userryanvm@gmail.com
push dateThu, 01 Jun 2017 15:54:15 +0000
treeherdermozilla-central@cac2fd43de81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1364975
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
toolkit/components/extensions/ext-privacy.js
toolkit/components/extensions/schemas/privacy.json
toolkit/components/extensions/test/xpcshell/test_ext_privacy.js
--- 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>&lt;link rel='prefetch' ...&gt;</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() {