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:
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user