/* import-globals-from head_addons.js */
const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet";
const PREF_SYSTEM_ADDON_UPDATE_URL = "extensions.systemAddon.update.url";
const PREF_SYSTEM_ADDON_UPDATE_ENABLED =
"extensions.systemAddon.update.enabled";
// See bug 1507255
Services.prefs.setBoolPref("media.gmp-manager.updateEnabled", true);
function root(server) {
let { primaryScheme, primaryHost, primaryPort } = server.identity;
return `${primaryScheme}://${primaryHost}:${primaryPort}/data`;
}
XPCOMUtils.defineLazyGetter(this, "testserver", () => {
let server = new HttpServer();
server.start();
Services.prefs.setCharPref(
PREF_SYSTEM_ADDON_UPDATE_URL,
`${root(server)}/update.xml`
);
return server;
});
async function serveSystemUpdate(xml, perform_update) {
testserver.registerPathHandler("/data/update.xml", (request, response) => {
response.write(xml);
});
try {
await perform_update();
} finally {
testserver.registerPathHandler("/data/update.xml", null);
}
}
// Runs an update check making it use the passed in xml string. Uses the direct
// call to the update function so we get rejections on failure.
async function installSystemAddons(xml, waitIDs = []) {
info("Triggering system add-on update check.");
await serveSystemUpdate(
xml,
async function () {
let { XPIProvider } = ChromeUtils.import(
"resource://gre/modules/addons/XPIProvider.jsm"
);
await Promise.all([
XPIProvider.updateSystemAddons(),
...waitIDs.map(id => promiseWebExtensionStartup(id)),
]);
},
testserver
);
}
// Runs a full add-on update check which will in some cases do a system add-on
// update check. Always succeeds.
async function updateAllSystemAddons(xml) {
info("Triggering full add-on update check.");
await serveSystemUpdate(
xml,
function () {
return new Promise(resolve => {
Services.obs.addObserver(function observer() {
Services.obs.removeObserver(
observer,
"addons-background-update-complete"
);
resolve();
}, "addons-background-update-complete");
// Trigger the background update timer handler
gInternalManager.notify(null);
});
},
testserver
);
}
// Builds an update.xml file for an update check based on the data passed.
function buildSystemAddonUpdates(addons) {
let xml = `\n\n\n`;
if (addons) {
xml += ` \n`;
for (let addon of addons) {
if (addon.xpi) {
testserver.registerFile(`/data/${addon.path}`, addon.xpi);
}
xml += ` \n`;
}
xml += ` \n`;
}
xml += `\n`;
return xml;
}
let _systemXPIs = new Map();
function getSystemAddonXPI(num, version) {
let key = `${num}:${version}`;
if (!_systemXPIs.has(key)) {
_systemXPIs.set(
key,
AddonTestUtils.createTempWebExtensionFile({
manifest: {
name: `System Add-on ${num}`,
version,
browser_specific_settings: {
gecko: {
id: `system${num}@tests.mozilla.org`,
},
},
},
})
);
}
return _systemXPIs.get(key);
}
async function initSystemAddonDirs() {
let hiddenSystemAddonDir = FileUtils.getDir(
"ProfD",
["sysfeatures", "hidden"],
true
);
let system1_1 = await getSystemAddonXPI(1, "1.0");
system1_1.copyTo(hiddenSystemAddonDir, "system1@tests.mozilla.org.xpi");
let system2_1 = await getSystemAddonXPI(2, "1.0");
system2_1.copyTo(hiddenSystemAddonDir, "system2@tests.mozilla.org.xpi");
let prefilledSystemAddonDir = FileUtils.getDir(
"ProfD",
["sysfeatures", "prefilled"],
true
);
let system2_2 = await getSystemAddonXPI(2, "2.0");
system2_2.copyTo(prefilledSystemAddonDir, "system2@tests.mozilla.org.xpi");
let system3_2 = await getSystemAddonXPI(3, "2.0");
system3_2.copyTo(prefilledSystemAddonDir, "system3@tests.mozilla.org.xpi");
}
/**
* Returns current system add-on update directory (stored in pref).
*/
function getCurrentSystemAddonUpdatesDir() {
const updatesDir = FileUtils.getDir("ProfD", ["features"], false);
let dir = updatesDir.clone();
let set = JSON.parse(Services.prefs.getCharPref(PREF_SYSTEM_ADDON_SET));
dir.append(set.directory);
return dir;
}
/**
* Removes all files from system add-on update directory.
*/
function clearSystemAddonUpdatesDir() {
const updatesDir = FileUtils.getDir("ProfD", ["features"], false);
// Delete any existing directories
if (updatesDir.exists()) {
updatesDir.remove(true);
}
Services.prefs.clearUserPref(PREF_SYSTEM_ADDON_SET);
}
registerCleanupFunction(() => {
clearSystemAddonUpdatesDir();
});
/**
* Installs a known set of add-ons into the system add-on update directory.
*/
async function buildPrefilledUpdatesDir() {
clearSystemAddonUpdatesDir();
// Build the test set
let dir = FileUtils.getDir("ProfD", ["features", "prefilled"], true);
let xpi = await getSystemAddonXPI(2, "2.0");
xpi.copyTo(dir, "system2@tests.mozilla.org.xpi");
xpi = await getSystemAddonXPI(3, "2.0");
xpi.copyTo(dir, "system3@tests.mozilla.org.xpi");
// Mark these in the past so the startup file scan notices when files have changed properly
FileUtils.getFile("ProfD", [
"features",
"prefilled",
"system2@tests.mozilla.org.xpi",
]).lastModifiedTime -= 10000;
FileUtils.getFile("ProfD", [
"features",
"prefilled",
"system3@tests.mozilla.org.xpi",
]).lastModifiedTime -= 10000;
Services.prefs.setCharPref(
PREF_SYSTEM_ADDON_SET,
JSON.stringify({
schema: 1,
directory: dir.leafName,
addons: {
"system2@tests.mozilla.org": {
version: "2.0",
},
"system3@tests.mozilla.org": {
version: "2.0",
},
},
})
);
}
/**
* Check currently installed ssystem add-ons against a set of conditions.
*
* @param {Array