Bug 1341277 - Part 3: Update ext-privacy.js to support disabling and re-enabling settings. r=aswan

MozReview-Commit-ID: 4Yf0uxsoXHP
This commit is contained in:
Bob Silverberg
2017-02-23 09:45:37 -05:00
parent 7a75bd36e0
commit 2f8174e4aa
5 changed files with 395 additions and 18 deletions

View File

@@ -13,6 +13,28 @@ const {
ExtensionError,
} = ExtensionUtils;
/* eslint-disable mozilla/balanced-listeners */
extensions.on("startup", async (type, extension) => {
if (["ADDON_ENABLE", "ADDON_UPGRADE", "ADDON_DOWNGRADE"].includes(extension.startupReason)) {
await ExtensionPreferencesManager.enableAll(extension);
}
});
extensions.on("shutdown", async (type, extension) => {
switch (extension.shutdownReason) {
case "ADDON_DISABLE":
case "ADDON_DOWNGRADE":
case "ADDON_UPGRADE":
await ExtensionPreferencesManager.disableAll(extension);
break;
case "ADDON_UNINSTALL":
await ExtensionPreferencesManager.removeAll(extension);
break;
}
});
/* eslint-enable mozilla/balanced-listeners */
function checkScope(scope) {
if (scope && scope !== "regular") {
throw new ExtensionError(
@@ -20,8 +42,7 @@ function checkScope(scope) {
}
}
function getAPI(extension, context, name, callback) {
let anythingSet = false;
function getAPI(extension, name, callback) {
return {
async get(details) {
return {
@@ -34,23 +55,12 @@ function getAPI(extension, context, name, callback) {
},
async set(details) {
checkScope(details.scope);
if (!anythingSet) {
anythingSet = true;
context.callOnClose({
close: async () => {
if (["ADDON_DISABLE", "ADDON_UNINSTALL"].includes(extension.shutdownReason)) {
await ExtensionPreferencesManager.unsetAll(extension);
anythingSet = false;
}
},
});
}
return await ExtensionPreferencesManager.setSetting(
extension, name, details.value);
},
async clear(details) {
checkScope(details.scope);
return await ExtensionPreferencesManager.unsetSetting(
return await ExtensionPreferencesManager.removeSetting(
extension, name);
},
};
@@ -125,7 +135,7 @@ extensions.registerSchemaAPI("privacy.network", "addon_parent", context => {
return {
privacy: {
network: {
networkPredictionEnabled: getAPI(extension, context,
networkPredictionEnabled: getAPI(extension,
"network.networkPredictionEnabled",
() => {
return Preferences.get("network.predictor.enabled") &&
@@ -133,7 +143,7 @@ extensions.registerSchemaAPI("privacy.network", "addon_parent", context => {
Preferences.get("network.http.speculative-parallel-limit") > 0 &&
!Preferences.get("network.dns.disablePrefetch");
}),
webRTCIPHandlingPolicy: getAPI(extension, context,
webRTCIPHandlingPolicy: getAPI(extension,
"network.webRTCIPHandlingPolicy",
() => {
if (Preferences.get("media.peerconnection.ice.proxy_only")) {
@@ -153,7 +163,7 @@ extensions.registerSchemaAPI("privacy.network", "addon_parent", context => {
}),
},
websites: {
hyperlinkAuditingEnabled: getAPI(extension, context,
hyperlinkAuditingEnabled: getAPI(extension,
"websites.hyperlinkAuditingEnabled",
() => {
return Preferences.get("browser.send_pings");

View File

@@ -20,7 +20,7 @@ AddonTestUtils.init(this);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
add_task(async function test_privacy() {
// Create a object to hold the values to which we will initialize the prefs.
// Create an object to hold the values to which we will initialize the prefs.
const SETTINGS = {
"network.networkPredictionEnabled": {
"network.predictor.enabled": true,

View File

@@ -0,0 +1,185 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyGetter(this, "Management", () => {
const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
return Management;
});
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPreferencesManager",
"resource://gre/modules/ExtensionPreferencesManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
const {
createAppInfo,
promiseShutdownManager,
promiseStartupManager,
} = AddonTestUtils;
AddonTestUtils.init(this);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
function awaitEvent(eventName) {
return new Promise(resolve => {
let listener = (_eventName, ...args) => {
if (_eventName === eventName) {
Management.off(eventName, listener);
resolve(...args);
}
};
Management.on(eventName, listener);
});
}
function awaitPrefChange(prefName) {
return new Promise(resolve => {
let listener = (args) => {
Preferences.ignore(prefName, listener);
resolve();
};
Preferences.observe(prefName, listener);
});
}
add_task(async function test_disable() {
const OLD_ID = "old_id@tests.mozilla.org";
const NEW_ID = "new_id@tests.mozilla.org";
const PREF_TO_WATCH = "network.http.speculative-parallel-limit";
// Create an object to hold the values to which we will initialize the prefs.
const PREFS = {
"network.predictor.enabled": true,
"network.prefetch-next": true,
"network.http.speculative-parallel-limit": 10,
"network.dns.disablePrefetch": false,
};
// Set prefs to our initial values.
for (let pref in PREFS) {
Preferences.set(pref, PREFS[pref]);
}
do_register_cleanup(() => {
// Reset the prefs.
for (let pref in PREFS) {
Preferences.reset(pref);
}
});
function checkPrefs(expected) {
for (let pref in PREFS) {
let msg = `${pref} set correctly.`;
let expectedValue = expected ? PREFS[pref] : !PREFS[pref];
if (pref === "network.http.speculative-parallel-limit") {
expectedValue = expected ? ExtensionPreferencesManager.getDefaultValue(pref) : 0;
}
equal(Preferences.get(pref), expectedValue, msg);
}
}
async function background() {
browser.test.onMessage.addListener(async (msg, data) => {
await browser.privacy.network.networkPredictionEnabled.set(data);
let settingData = await browser.privacy.network.networkPredictionEnabled.get({});
browser.test.sendMessage("privacyData", settingData);
});
}
// Create an array of extensions to install.
let testExtensions = [
ExtensionTestUtils.loadExtension({
background,
manifest: {
applications: {
gecko: {
id: OLD_ID,
},
},
permissions: ["privacy"],
},
useAddonManager: "temporary",
}),
ExtensionTestUtils.loadExtension({
background,
manifest: {
applications: {
gecko: {
id: NEW_ID,
},
},
permissions: ["privacy"],
},
useAddonManager: "temporary",
}),
];
await promiseStartupManager();
for (let extension of testExtensions) {
await extension.startup();
}
// Set the value to true for the older extension.
testExtensions[0].sendMessage("set", {value: true});
let data = await testExtensions[0].awaitMessage("privacyData");
ok(data.value, "Value set to true for the older extension.");
// Set the value to false for the newest extension.
testExtensions[1].sendMessage("set", {value: false});
data = await testExtensions[1].awaitMessage("privacyData");
ok(!data.value, "Value set to false for the newest extension.");
// Verify the prefs have been set to match the "false" setting.
checkPrefs(false);
// Disable the newest extension.
let disabledPromise = awaitPrefChange(PREF_TO_WATCH);
let newAddon = await AddonManager.getAddonByID(NEW_ID);
newAddon.userDisabled = true;
await disabledPromise;
// Verify the prefs have been set to match the "true" setting.
checkPrefs(true);
// Disable the older extension.
disabledPromise = awaitPrefChange(PREF_TO_WATCH);
let oldAddon = await AddonManager.getAddonByID(OLD_ID);
oldAddon.userDisabled = true;
await disabledPromise;
// Verify the prefs have reverted back to their initial values.
for (let pref in PREFS) {
equal(Preferences.get(pref), PREFS[pref], `${pref} reset correctly.`);
}
// Re-enable the newest extension.
let enabledPromise = awaitEvent("ready");
newAddon.userDisabled = false;
await enabledPromise;
// Verify the prefs have been set to match the "false" setting.
checkPrefs(false);
// Re-enable the older extension.
enabledPromise = awaitEvent("ready");
oldAddon.userDisabled = false;
await enabledPromise;
// Verify the prefs have remained set to match the "false" setting.
checkPrefs(false);
for (let extension of testExtensions) {
await extension.unload();
}
await promiseShutdownManager();
});

View File

@@ -0,0 +1,180 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyGetter(this, "Management", () => {
const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
return Management;
});
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
const {
createAppInfo,
createTempWebExtensionFile,
promiseAddonEvent,
promiseCompleteAllInstalls,
promiseFindAddonUpdates,
promiseShutdownManager,
promiseStartupManager,
} = AddonTestUtils;
AddonTestUtils.init(this);
// Allow for unsigned addons.
AddonTestUtils.overrideCertDB();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
function awaitEvent(eventName) {
return new Promise(resolve => {
let listener = (_eventName, ...args) => {
if (_eventName === eventName) {
Management.off(eventName, listener);
resolve(...args);
}
};
Management.on(eventName, listener);
});
}
add_task(async function test_privacy_update() {
// Create a object to hold the values to which we will initialize the prefs.
const PREFS = {
"network.predictor.enabled": true,
"network.prefetch-next": true,
"network.http.speculative-parallel-limit": 10,
"network.dns.disablePrefetch": false,
};
const EXTENSION_ID = "test_privacy_addon_update@tests.mozilla.org";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
// Set prefs to our initial values.
for (let pref in PREFS) {
Preferences.set(pref, PREFS[pref]);
}
do_register_cleanup(() => {
// Reset the prefs.
for (let pref in PREFS) {
Preferences.reset(pref);
}
});
async function background() {
browser.test.onMessage.addListener(async (msg, data) => {
let settingData;
switch (msg) {
case "get":
settingData = await browser.privacy.network.networkPredictionEnabled.get({});
browser.test.sendMessage("privacyData", settingData);
break;
case "set":
await browser.privacy.network.networkPredictionEnabled.set(data);
settingData = await browser.privacy.network.networkPredictionEnabled.get({});
browser.test.sendMessage("privacyData", settingData);
break;
}
});
}
const testServer = createHttpServer();
const port = testServer.identity.primaryPort;
// The test extension uses an insecure update url.
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
testServer.registerPathHandler("/test_update.json", (request, response) => {
response.write(`{
"addons": {
"${EXTENSION_ID}": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:${port}/addons/test_privacy-2.0.xpi"
}
]
}
}
}`);
});
let webExtensionFile = createTempWebExtensionFile({
manifest: {
version: "2.0",
applications: {
gecko: {
id: EXTENSION_ID,
},
},
permissions: ["privacy"],
},
background,
});
testServer.registerFile("/addons/test_privacy-2.0.xpi", webExtensionFile);
await promiseStartupManager();
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest: {
"version": "1.0",
"applications": {
"gecko": {
"id": EXTENSION_ID,
"update_url": `http://localhost:${port}/test_update.json`,
},
},
permissions: ["privacy"],
},
background,
});
await extension.startup();
// Change the value to false.
extension.sendMessage("set", {value: false});
let data = await extension.awaitMessage("privacyData");
ok(!data.value, "get returns expected value after setting.");
let addon = await AddonManager.getAddonByID(EXTENSION_ID);
equal(addon.version, "1.0", "The installed addon has the expected version.");
let update = await promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
let promiseInstalled = promiseAddonEvent("onInstalled");
await promiseCompleteAllInstalls([install]);
let startupPromise = awaitEvent("ready");
let [updated_addon] = await promiseInstalled;
equal(updated_addon.version, "2.0", "The updated addon has the expected version.");
extension.extension = await startupPromise;
extension.attachListeners();
extension.sendMessage("get");
data = await extension.awaitMessage("privacyData");
ok(!data.value, "get returns expected value after updating.");
// Verify the prefs are still set to match the "false" setting.
for (let pref in PREFS) {
let msg = `${pref} set correctly.`;
let expectedValue = pref === "network.http.speculative-parallel-limit" ? 0 : !PREFS[pref];
equal(Preferences.get(pref), expectedValue, msg);
}
await extension.unload();
await updated_addon.uninstall();
await promiseShutdownManager();
});

View File

@@ -49,6 +49,8 @@ skip-if = release_or_beta
[test_ext_onmessage_removelistener.js]
skip-if = true # This test no longer tests what it is meant to test.
[test_ext_privacy.js]
[test_ext_privacy_disable.js]
[test_ext_privacy_update.js]
[test_ext_runtime_connect_no_receiver.js]
[test_ext_runtime_getBrowserInfo.js]
[test_ext_runtime_getPlatformInfo.js]