Backed out changeset 8952c559acfb (bug 1512436) for multiple failures on a CLOSED TREE.

This commit is contained in:
Oana Pop Rus 2019-01-19 06:35:44 +02:00
parent bdea6eafb0
commit 6ab64fd6f3
9 changed files with 77 additions and 290 deletions

View File

@ -1434,7 +1434,7 @@ class Extension extends ExtensionData {
* @property {TabManager} tabManager
*/
static getBootstrapScope() {
static getBootstrapScope(id, file) {
return new BootstrapScope();
}
@ -2050,7 +2050,7 @@ class Dictionary extends ExtensionData {
this.startupData = addonData.startupData;
}
static getBootstrapScope() {
static getBootstrapScope(id, file) {
return new DictionaryBootstrapScope();
}
@ -2080,7 +2080,7 @@ class Langpack extends ExtensionData {
this.manifestCacheKey = [addonData.id, addonData.version];
}
static getBootstrapScope() {
static getBootstrapScope(id, file) {
return new LangpackBootstrapScope();
}

View File

@ -2059,23 +2059,6 @@ var AddonManagerInternal = {
.installTemporaryAddon(aFile);
},
/**
* Installs an add-on from a built-in location
* (ie a resource: url referencing assets shipped with the application)
*
* @param aBase
* A string containing the base URL. Must be a resource: URL.
* @returns a Promise that resolves when the addon is installed.
*/
installBuiltinAddon(aBase) {
if (!gStarted)
throw Components.Exception("AddonManager is not initialized",
Cr.NS_ERROR_NOT_INITIALIZED);
return AddonManagerInternal._getProviderByName("XPIProvider")
.installBuiltinAddon(aBase);
},
syncGetAddonIDByInstanceID(aInstanceID) {
if (!gStarted)
throw Components.Exception("AddonManager is not initialized",
@ -3352,10 +3335,6 @@ var AddonManager = {
return AddonManagerInternal.installTemporaryAddon(aDirectory);
},
installBuiltinAddon(aBase) {
return AddonManagerInternal.installBuiltinAddon(aBase);
},
addManagerListener(aListener) {
AddonManagerInternal.addManagerListener(aListener);
},

View File

@ -245,14 +245,10 @@ class AddonsList {
} catch (e) {
file = new nsFile(addon.path);
}
} else if (addon.path) {
} else {
file = new nsFile(addon.path);
}
if (!file) {
continue;
}
this.xpis.push(file);
if (addon.enabled) {

View File

@ -82,7 +82,6 @@ const TOOLKIT_ID = "toolkit@mozilla.org";
const KEY_APP_SYSTEM_ADDONS = "app-system-addons";
const KEY_APP_SYSTEM_DEFAULTS = "app-system-defaults";
const KEY_APP_BUILTINS = "app-builtin";
const KEY_APP_SYSTEM_LOCAL = "app-system-local";
const KEY_APP_SYSTEM_SHARE = "app-system-share";
const KEY_APP_GLOBAL = "app-global";
@ -112,8 +111,7 @@ const PROP_JSON_FIELDS = ["id", "syncGUID", "version", "type",
"seen", "dependencies",
"userPermissions", "icons", "iconURL",
"blocklistState", "blocklistURL", "startupData",
"previewImage", "hidden", "installTelemetryInfo",
"rootURI"];
"previewImage", "hidden", "installTelemetryInfo"];
const LEGACY_TYPES = new Set([
"extension",
@ -237,7 +235,6 @@ class AddonInternal {
this.startupData = null;
this._hidden = false;
this.installTelemetryInfo = null;
this.rootURI = null;
this.inDatabase = false;
@ -261,6 +258,10 @@ class AddonInternal {
this.addedToDatabase();
}
if (!addonData._sourceBundle) {
throw new Error("Expected passed argument to contain a path");
}
this._sourceBundle = addonData._sourceBundle;
}
}
@ -341,9 +342,8 @@ class AddonInternal {
return this.signedState == AddonManager.SIGNEDSTATE_SYSTEM;
case KEY_APP_SYSTEM_DEFAULTS:
case KEY_APP_BUILTINS:
case KEY_APP_TEMPORARY:
// Temporary and built-in add-ons do not require signing.
// Temporary and built-in system add-ons do not require signing.
return true;
case KEY_APP_SYSTEM_SHARE:
@ -1336,14 +1336,12 @@ this.XPIDatabase = {
// Make AddonInternal instances from the loaded data and save them
let addonDB = new Map();
await forEach(inputAddons.addons, loadedAddon => {
if (loadedAddon.path) {
try {
loadedAddon._sourceBundle = new nsIFile(loadedAddon.path);
} catch (e) {
// We can fail here when the path is invalid, usually from the
// wrong OS
logger.warn("Could not find source bundle for add-on " + loadedAddon.id, e);
}
try {
loadedAddon._sourceBundle = new nsIFile(loadedAddon.path);
} catch (e) {
// We can fail here when the path is invalid, usually from the
// wrong OS
logger.warn("Could not find source bundle for add-on " + loadedAddon.id, e);
}
loadedAddon.location = XPIStates.getLocation(loadedAddon.location);
@ -2334,7 +2332,6 @@ this.XPIDatabaseReconcile = {
// Load the manifest from the add-on.
let file = new nsIFile(aAddonState.path);
aNewAddon = XPIInstall.syncLoadManifestFromFile(file, aLocation);
aNewAddon.rootURI = XPIInternal.getURIForResourceInFile(file, "").spec;
}
// The add-on in the manifest should match the add-on ID.
if (aNewAddon.id != aId) {
@ -2430,9 +2427,6 @@ this.XPIDatabaseReconcile = {
if (!aNewAddon) {
let file = new nsIFile(aAddonState.path);
aNewAddon = XPIInstall.syncLoadManifestFromFile(file, aLocation, aOldAddon);
aNewAddon.rootURI = XPIInternal.getURIForResourceInFile(file, "").spec;
} else if (!aNewAddon.rootURI) {
aNewAddon.rootURI = aOldAddon.rootURI;
}
// The ID in the manifest that was loaded must match the ID of the old
@ -2509,7 +2503,6 @@ this.XPIDatabaseReconcile = {
try {
let file = new nsIFile(aAddonState.path);
manifest = XPIInstall.syncLoadManifestFromFile(file, aLocation);
manifest.rootURI = aOldAddon.rootURI;
} catch (err) {
// If we can no longer read the manifest, it is no longer compatible.
aOldAddon.brokenManifest = true;
@ -2555,8 +2548,7 @@ this.XPIDatabaseReconcile = {
*/
isAppBundledLocation(location) {
return (location.name == KEY_APP_GLOBAL ||
location.name == KEY_APP_SYSTEM_DEFAULTS ||
location.name == KEY_APP_BUILTINS);
location.name == KEY_APP_SYSTEM_DEFAULTS);
},
/**
@ -2616,9 +2608,6 @@ this.XPIDatabaseReconcile = {
} else {
newAddon = oldAddon;
}
newAddon.rootURI = newAddon.rootURI || xpiState.rootURI;
return newAddon;
},

View File

@ -84,7 +84,7 @@ const PREF_XPI_WHITELIST_REQUIRED = "xpinstall.whitelist.required";
const TOOLKIT_ID = "toolkit@mozilla.org";
/* globals BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, PREF_BRANCH_INSTALLED_ADDON, PREF_SYSTEM_ADDON_SET, TEMPORARY_ADDON_SUFFIX, XPI_PERMISSION, XPIStates, getURIForResourceInFile, iterDirectory */
/* globals BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, PREF_BRANCH_INSTALLED_ADDON, PREF_SYSTEM_ADDON_SET, TEMPORARY_ADDON_SUFFIX, XPI_PERMISSION, XPIStates, iterDirectory */
const XPI_INTERNAL_SYMBOLS = [
"BOOTSTRAP_REASONS",
"KEY_APP_SYSTEM_ADDONS",
@ -94,7 +94,6 @@ const XPI_INTERNAL_SYMBOLS = [
"TEMPORARY_ADDON_SUFFIX",
"XPI_PERMISSION",
"XPIStates",
"getURIForResourceInFile",
"iterDirectory",
];
@ -210,6 +209,16 @@ class Package {
return Services.io.newURI(path.join("/"), null, this.rootURI);
}
async getManifestFile() {
if (await this.hasResource("manifest.json")) {
return "manifest.json";
}
if (await this.hasResource("install.rdf")) {
return "install.rdf";
}
return null;
}
async readString(...path) {
let buffer = await this.readBinary(...path);
return new TextDecoder().decode(buffer);
@ -1518,7 +1527,6 @@ class AddonInstall {
// Update the metadata in the database
this.addon._sourceBundle = file;
this.addon.rootURI = getURIForResourceInFile(file, "").spec;
this.addon.visible = true;
if (isUpgrade) {
@ -3268,7 +3276,6 @@ var XPIInstall = {
// Install the add-on
addon._sourceBundle = location.installer.installAddon({ id, source: file, action: "copy" });
addon.rootURI = XPIInternal.getURIForResourceInFile(addon._sourceBundle, "").spec;
XPIStates.addAddon(addon);
logger.debug(`Installed distribution add-on ${id}`);
@ -3642,75 +3649,9 @@ var XPIInstall = {
flushJarCache(aFile);
}
let addon = await loadManifestFromFile(aFile, installLocation);
addon.rootURI = getURIForResourceInFile(aFile, "").spec;
await this._activateAddon(addon, {temporarilyInstalled: true});
installLocation.installer.installAddon({ id: addon.id, source: aFile });
logger.debug(`Install of temporary addon in ${aFile.path} completed.`);
return addon.wrapper;
},
/**
* Installs an add-on from a built-in location
* (ie a resource: url referencing assets shipped with the application)
*
* @param {string} base
* A string containing the base URL. Must be a resource: URL.
* @returns {Promise}
* A Promise that resolves when the addon is installed.
*/
async installBuiltinAddon(base) {
let baseURL = Services.io.newURI(base);
// WebExtensions need to be able to iterate through the contents of
// an extension (for localization). It knows how to do this with
// jar: and file: URLs, so translate the provided base URL to
// something it can use.
if (baseURL.scheme !== "resource") {
throw new Error("Built-in addons must use resource: URLS");
}
let root = Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsISubstitutingProtocolHandler)
.resolveURI(baseURL);
let rootURI = Services.io.newURI(root);
// Enough of the Package interface to allow loadManifest() to work.
let pkg = {
rootURI: Services.io.newURI("manifest.json", null, rootURI),
filePath: baseURL,
file: null,
verifySignedState() {
return {
signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED,
cert: null,
};
},
hasResource() {
return true;
},
};
let addon = await loadManifest(pkg, XPIInternal.BuiltInLocation);
addon.rootURI = root;
await this._activateAddon(addon);
},
/**
* Activate a newly installed addon.
* This function handles all the bookkeeping related to a new addon
* and invokes whatever bootstrap methods are necessary.
* Note that this function is only used for temporary and built-in
* installs, it is very similar to AddonInstall::startInstall().
* It would be great to merge this function with that one some day.
*
* @param {AddonInternal} addon The addon to activate
* @param {object} [extraParams] Any extra parameters to pass to the
* bootstrap install() method
*
* @returns {Promise<void>}
*/
async _activateAddon(addon, extraParams = {}) {
if (addon.appDisabled) {
let message = `Add-on ${addon.id} is not compatible with application version.`;
@ -3728,35 +3669,47 @@ var XPIInstall = {
let oldAddon = await XPIDatabase.getVisibleAddonForID(addon.id);
let extraParams = {};
extraParams.temporarilyInstalled = true;
let install = () => {
addon.state = AddonManager.STATE_INSTALLED;
logger.debug(`Install of temporary addon in ${aFile.path} completed.`);
addon.visible = true;
addon.enabled = true;
addon.active = true;
// WebExtension themes are installed as disabled, fix that here.
addon.userDisabled = false;
addon = XPIDatabase.addToDatabase(addon, addon._sourceBundle ? addon._sourceBundle.path : null);
addon = XPIDatabase.addToDatabase(addon, addon._sourceBundle.path);
XPIStates.addAddon(addon);
XPIDatabase.saveChanges();
XPIStates.save();
};
AddonManagerPrivate.callAddonListeners("onInstalling", addon.wrapper);
let promise;
if (oldAddon) {
logger.warn(`Addon with ID ${oldAddon.id} already installed, ` +
"older version will be disabled");
addon.installDate = oldAddon.installDate;
await XPIInternal.BootstrapScope.get(oldAddon).update(
promise = XPIInternal.BootstrapScope.get(oldAddon).update(
addon, true, install);
} else {
addon.installDate = Date.now();
install();
let bootstrap = XPIInternal.BootstrapScope.get(addon);
await bootstrap.install(undefined, true, extraParams);
promise = bootstrap.install(undefined, true, {temporarilyInstalled: true});
}
AddonManagerPrivate.callAddonListeners("onInstalling", addon.wrapper,
false);
await promise;
AddonManagerPrivate.callInstallListeners("onExternalInstall",
null, addon.wrapper,
oldAddon ? oldAddon.wrapper : null,
@ -3766,6 +3719,8 @@ var XPIInstall = {
// Notify providers that a new theme has been enabled.
if (addon.type === "theme")
AddonManagerPrivate.notifyAddonChanged(addon.id, addon.type, false);
return addon.wrapper;
},
/**

View File

@ -86,7 +86,6 @@ const KEY_APP_FEATURES = "XREAppFeat";
const KEY_APP_PROFILE = "app-profile";
const KEY_APP_SYSTEM_ADDONS = "app-system-addons";
const KEY_APP_SYSTEM_DEFAULTS = "app-system-defaults";
const KEY_APP_BUILTINS = "app-builtin";
const KEY_APP_GLOBAL = "app-global";
const KEY_APP_SYSTEM_LOCAL = "app-system-local";
const KEY_APP_SYSTEM_SHARE = "app-system-share";
@ -105,7 +104,7 @@ const XPI_PERMISSION = "install";
const XPI_SIGNATURE_CHECK_PERIOD = 24 * 60 * 60;
const DB_SCHEMA = 29;
const DB_SCHEMA = 28;
function encoded(strings, ...values) {
let result = [];
@ -411,7 +410,6 @@ const JSON_FIELDS = Object.freeze([
"loader",
"lastModifiedTime",
"path",
"rootURI",
"runInSafeMode",
"signedState",
"startupData",
@ -434,12 +432,6 @@ class XPIState {
}
}
// Builds prior to be 1512436 did not include the rootURI property.
// If we're updating from such a build, add that property now.
if (!("rootURI" in this) && this.file) {
this.rootURI = getURIForResourceInFile(this.file, "").spec;
}
if (!this.telemetryKey) {
this.telemetryKey = this.getTelemetryKey();
}
@ -470,7 +462,7 @@ class XPIState {
return this.file && this.file.path;
}
set path(path) {
this.file = path ? getFile(path, this.location.dir) : null;
this.file = getFile(path, this.location.dir);
}
/**
@ -502,7 +494,6 @@ class XPIState {
lastModifiedTime: this.lastModifiedTime,
loader: this.loader,
path: this.relativePath,
rootURI: this.rootURI,
runInSafeMode: this.runInSafeMode,
signedState: this.signedState,
telemetryKey: this.telemetryKey,
@ -590,30 +581,13 @@ class XPIState {
this.runInSafeMode = canRunInSafeMode(aDBAddon);
this.signedState = aDBAddon.signedState;
this.file = aDBAddon._sourceBundle;
this.rootURI = aDBAddon.rootURI;
if (aUpdated || mustGetMod) {
let file = this.file;
// Built-in addons should have jar: rootURIs, use the mod time
// for the containing jar file for those.
if (!file) {
let fileUrl = Services.io.newURI(this.rootURI);
if (fileUrl.QueryInterface(Ci.nsIJARURI)) {
fileUrl = fileUrl.JARFile;
}
if (fileUrl.QueryInterface(Ci.nsIFileURL)) {
file = fileUrl.file;
}
}
if (file) {
this.getModTime(file);
if (this.lastModifiedTime != aDBAddon.updateDate) {
aDBAddon.updateDate = this.lastModifiedTime;
if (XPIDatabase.initialized) {
XPIDatabase.saveChanges();
}
this.getModTime(this.file);
if (this.lastModifiedTime != aDBAddon.updateDate) {
aDBAddon.updateDate = this.lastModifiedTime;
if (XPIDatabase.initialized) {
XPIDatabase.saveChanges();
}
}
}
@ -836,17 +810,6 @@ class XPIStateLocation extends Map {
get isSystem() {
return false;
}
get isBuiltin() {
return false;
}
// If this property is false, it does not implement readAddons()
// interface. This is used for the temporary and built-in locations
// that do not correspond to a physical location that can be scanned.
get enumerable() {
return true;
}
}
class TemporaryLocation extends XPIStateLocation {
@ -872,45 +835,17 @@ class TemporaryLocation extends XPIStateLocation {
return {};
}
get isTemporary() {
return true;
readAddons() {
return new Map();
}
get enumerable() {
return false;
get isTemporary() {
return true;
}
}
var TemporaryInstallLocation = new TemporaryLocation(KEY_APP_TEMPORARY);
/**
* A "location" for addons installed from assets packged into the app.
*/
var BuiltInLocation = new class _BuiltInLocation extends XPIStateLocation {
constructor() {
super(KEY_APP_BUILTINS, null, null);
this.locked = false;
}
// The installer object is responsible for moving files around on disk
// when (un)installing an addon. Since this location handles only addons
// that are embedded within the browser, these are no-ops.
makeInstaller() {
return {
installAddon() {},
uninstallAddon() {},
};
}
get isBuiltin() {
return true;
}
get enumerable() {
return false;
}
}();
/**
* An object which identifies a directory install location for add-ons. The
* location consists of a directory which contains the add-ons installed in the
@ -1056,7 +991,7 @@ class DirectoryLocation extends XPIStateLocation {
*
* This location should point either to a XPI, or a directory in a local build.
*/
class SystemAddonDefaults extends DirectoryLocation {
class BuiltInLocation extends DirectoryLocation {
/**
* Read the manifest of allowed add-ons and build a mapping between ID and URI
* for each.
@ -1362,7 +1297,7 @@ var XPIStates = {
continue;
}
if (!loc.enumerable) {
if (loc.isTemporary) {
continue;
}
@ -1677,10 +1612,11 @@ class BootstrapScope {
let params = {
id: addon.id,
version: addon.version,
resourceURI: Services.io.newURI(addon.rootURI),
installPath: this.file.clone(),
resourceURI: getURIForResourceInFile(this.file, ""),
signedState: addon.signedState,
temporarilyInstalled: addon.location.isTemporary,
builtIn: addon.location.isBuiltin,
builtIn: addon.location instanceof BuiltInLocation,
};
if (aMethod == "startup" && addon.startupData) {
@ -1738,21 +1674,21 @@ class BootstrapScope {
XPIProvider.addAddonsToCrashReporter();
}
logger.debug(`Loading bootstrap scope from ${this.addon.rootURI}`);
logger.debug(`Loading bootstrap scope from ${this.file.path}`);
if (this.addon.isWebExtension) {
switch (this.addon.type) {
case "extension":
case "theme":
this.scope = Extension.getBootstrapScope();
this.scope = Extension.getBootstrapScope(this.addon.id, this.file);
break;
case "locale":
this.scope = Langpack.getBootstrapScope();
this.scope = Langpack.getBootstrapScope(this.addon.id, this.file);
break;
case "dictionary":
this.scope = Dictionary.getBootstrapScope();
this.scope = Dictionary.getBootstrapScope(this.addon.id, this.file);
break;
default:
@ -1764,7 +1700,7 @@ class BootstrapScope {
throw new Error(`Cannot find loader for ${this.addon.loader}`);
}
this.scope = loader.loadScope(this.addon);
this.scope = loader.loadScope(this.addon, this.file);
}
}
@ -1902,10 +1838,7 @@ class BootstrapScope {
this.callBootstrapMethod("uninstall", reason, extraArgs);
}
this.unloadBootstrapScope();
if (this.file) {
XPIInstall.flushJarCache(this.file);
}
XPIInstall.flushJarCache(this.file);
XPIInstall.flushChromeCaches();
}
@ -2050,13 +1983,13 @@ var XPIProvider = {
return new DirectoryLocation(aName, dir, aScope, aLocked);
}
function SystemDefaultsLoc(name, scope, key, paths) {
function BuiltInLoc(name, scope, key, paths) {
try {
var dir = FileUtils.getDir(key, paths);
} catch (e) {
return null;
}
return new SystemAddonDefaults(name, dir, scope);
return new BuiltInLocation(name, dir, scope);
}
function SystemLoc(aName, aScope, aKey, aPaths) {
@ -2090,11 +2023,9 @@ var XPIProvider = {
[SystemLoc, KEY_APP_SYSTEM_ADDONS, AddonManager.SCOPE_PROFILE,
KEY_PROFILEDIR, [DIR_SYSTEM_ADDONS]],
[SystemDefaultsLoc, KEY_APP_SYSTEM_DEFAULTS, AddonManager.SCOPE_PROFILE,
[BuiltInLoc, KEY_APP_SYSTEM_DEFAULTS, AddonManager.SCOPE_PROFILE,
KEY_APP_FEATURES, []],
[() => BuiltInLocation, KEY_APP_BUILTINS, AddonManager.SCOPE_SYSTEM],
[DirectoryLoc, KEY_APP_SYSTEM_USER, AddonManager.SCOPE_USER,
"XREUSysExt", [Services.appinfo.ID], true],
@ -2803,9 +2734,8 @@ var XPIProvider = {
};
for (let meth of ["getInstallForFile", "getInstallForURL", "getInstallsByTypes",
"installTemporaryAddon", "installBuiltinAddon",
"isInstallAllowed", "isInstallEnabled",
"updateSystemAddons"]) {
"installTemporaryAddon", "isInstallAllowed",
"isInstallEnabled", "updateSystemAddons"]) {
XPIProvider[meth] = function() {
return XPIInstall[meth](...arguments);
};
@ -2821,7 +2751,6 @@ for (let meth of ["addonChanged", "getAddonByID", "getAddonBySyncGUID",
var XPIInternal = {
BOOTSTRAP_REASONS,
BootstrapScope,
BuiltInLocation,
DB_SCHEMA,
KEY_APP_SYSTEM_ADDONS,
KEY_APP_SYSTEM_DEFAULTS,

View File

@ -448,8 +448,8 @@ var SlightlyLessDodgyBootstrapMonitor = {
}
if (method !== "update" && method !== "uninstall") {
equal(params.resourceURI.spec, lastParams.resourceURI.spec,
`params.resourceURI should match last call`);
equal(params.installPath.path, lastParams.installPath.path,
`params.installPath should match last call`);
ok(params.resourceURI.equals(lastParams.resourceURI),
`params.resourceURI should match: "${params.resourceURI.spec}" == "${lastParams.resourceURI.spec}"`);

View File

@ -1,60 +0,0 @@
"use strict";
/* globals browser */
// Tests installing an extension from the built-in location.
add_task(async function test_builtin_location() {
let scopes = AddonManager.SCOPE_PROFILE | AddonManager.SCOPE_SYSTEM;
Services.prefs.setIntPref("extensions.enabledScopes", scopes);
Services.prefs.setBoolPref("extensions.webextensions.background-delayed-startup", false);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
await promiseStartupManager();
const ID = "builtin@tests.mozilla.org";
let xpi = await AddonTestUtils.createTempWebExtensionFile({
manifest: {
applications: {gecko: {id: ID}},
},
background() {
browser.test.sendMessage("started");
},
});
// The built-in location requires a resource: URL that maps to a
// jar: or file: URL. This would typically be something bundled
// into omni.ja but for testing we just use a temp file.
let base = Services.io.newURI(`jar:file:${xpi.path}!/`);
let resProto = Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler);
resProto.setSubstitution("ext-test", base);
let wrapper = ExtensionTestUtils.expectExtension(ID);
await AddonManager.installBuiltinAddon("resource://ext-test/");
await wrapper.awaitStartup();
await wrapper.awaitMessage("started");
ok(true, "Extension was installed successfully in built-in location");
let addon = await promiseAddonByID(ID);
notEqual(addon, null, "Addon is installed");
equal(addon.isActive, true, "Addon is active");
// After a restart, the extension should start up normally.
await promiseRestartManager();
await wrapper.awaitStartup();
await wrapper.awaitMessage("started");
ok(true, "Extension in built-in location ran after restart");
addon = await promiseAddonByID(ID);
notEqual(addon, null, "Addon is installed");
equal(addon.isActive, true, "Addon is active");
await wrapper.unload();
addon = await promiseAddonByID(ID);
equal(addon, null, "Addon is gone after uninstall");
await promiseShutdownManager();
});

View File

@ -63,7 +63,6 @@ tags = blocklist
# Times out during parallel runs on desktop
requesttimeoutfactor = 2
tags = blocklist
[test_builtin_location.js]
[test_cache_certdb.js]
[test_cacheflush.js]
[test_childprocess.js]