Bug 1452618 - make getAddonBlocklistEntry asynchronous, r=kmag

MozReview-Commit-ID: 4Kpx7M57404

--HG--
extra : rebase_source : 6c5a242b40288703fb424e81ea701eeba3c71a27
This commit is contained in:
Gijs Kruitbosch 2018-04-09 16:00:38 +01:00
parent a7f6ba42a1
commit 95b991b77b
8 changed files with 231 additions and 205 deletions

View File

@ -126,7 +126,8 @@ class MockBlocklist {
return this.addons.get(addon.id, Ci.nsIBlocklistService.STATE_NOT_BLOCKED);
}
getAddonBlocklistEntry(addon, appVersion, toolkitVersion) {
async getAddonBlocklistEntry(addon, appVersion, toolkitVersion) {
await Promise.resolve();
let state = this.getAddonBlocklistState(addon, appVersion, toolkitVersion);
if (state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
return {

View File

@ -867,7 +867,7 @@ function generateTemporaryInstallID(aFile) {
return id;
}
var loadManifest = async function(aPackage, aInstallLocation) {
var loadManifest = async function(aPackage, aInstallLocation, aOldAddon) {
async function loadFromRDF(aUri) {
let manifest = await aPackage.readString("install.rdf");
let addon = await loadManifestFromRDF(aUri, manifest);
@ -920,7 +920,7 @@ var loadManifest = async function(aPackage, aInstallLocation) {
}
}
addon.updateBlocklistState();
await addon.updateBlocklistState({oldAddon: aOldAddon});
addon.appDisabled = !isUsableAddon(addon);
defineSyncGUID(addon);
@ -928,10 +928,10 @@ var loadManifest = async function(aPackage, aInstallLocation) {
return addon;
};
var loadManifestFromFile = async function(aFile, aInstallLocation) {
var loadManifestFromFile = async function(aFile, aInstallLocation, aOldAddon) {
let pkg = Package.get(aFile);
try {
let addon = await loadManifest(pkg, aInstallLocation);
let addon = await loadManifest(pkg, aInstallLocation, aOldAddon);
return addon;
} finally {
pkg.close();
@ -1441,7 +1441,7 @@ class AddonInstall {
try {
try {
this.addon = await loadManifest(pkg, this.installLocation);
this.addon = await loadManifest(pkg, this.installLocation, this.existingAddon);
} catch (e) {
return Promise.reject([AddonManager.ERROR_CORRUPT_FILE, e]);
}
@ -1909,7 +1909,7 @@ var LocalAddonInstall = class extends AddonInstall {
});
this.existingAddon = addon;
this.addon.updateBlocklistState({oldAddon: this.existingAddon});
await this.addon.updateBlocklistState({oldAddon: this.existingAddon});
this.addon.updateDate = Date.now();
this.addon.installDate = addon ? addon.installDate : this.addon.updateDate;
@ -2302,7 +2302,7 @@ var DownloadAddonInstall = class extends AddonInstall {
* Notify listeners that the download completed.
*/
downloadCompleted() {
XPIDatabase.getVisibleAddonForID(this.addon.id, aAddon => {
XPIDatabase.getVisibleAddonForID(this.addon.id, async aAddon => {
if (aAddon)
this.existingAddon = aAddon;
@ -2315,7 +2315,7 @@ var DownloadAddonInstall = class extends AddonInstall {
} else {
this.addon.installDate = this.addon.updateDate;
}
this.addon.updateBlocklistState({oldAddon: this.existingAddon});
await this.addon.updateBlocklistState({oldAddon: this.existingAddon});
if (AddonManagerPrivate.callInstallListeners("onDownloadEnded",
this.listeners,

View File

@ -922,11 +922,11 @@ function getAllAliasesForTypes(aTypes) {
* A synchronous method for loading an add-on's manifest. This should only ever
* be used during startup or a sync load of the add-ons DB
*/
function syncLoadManifestFromFile(aFile, aInstallLocation) {
function syncLoadManifestFromFile(aFile, aInstallLocation, aOldAddon) {
let success = undefined;
let result = null;
loadManifestFromFile(aFile, aInstallLocation).then(val => {
loadManifestFromFile(aFile, aInstallLocation, aOldAddon).then(val => {
success = true;
result = val;
}, val => {
@ -4511,7 +4511,7 @@ AddonInternal.prototype = {
return app;
},
findBlocklistEntry() {
async findBlocklistEntry() {
let staticItem = findMatchingStaticBlocklistItem(this);
if (staticItem) {
let url = Services.urlFormatter.formatURLPref(PREF_BLOCKLIST_ITEM_URL);
@ -4524,7 +4524,7 @@ AddonInternal.prototype = {
return Blocklist.getAddonBlocklistEntry(this.wrapper);
},
updateBlocklistState(options = {}) {
async updateBlocklistState(options = {}) {
let {applySoftBlock = true, oldAddon = null, updateDatabase = true} = options;
if (oldAddon) {
@ -4534,7 +4534,7 @@ AddonInternal.prototype = {
}
let oldState = this.blocklistState;
let entry = this.findBlocklistEntry();
let entry = await this.findBlocklistEntry();
let newState = entry ? entry.state : Blocklist.STATE_NOT_BLOCKED;
this.blocklistState = newState;
@ -4962,7 +4962,7 @@ AddonWrapper.prototype = {
},
updateBlocklistState(applySoftBlock = true) {
addonFor(this).updateBlocklistState({applySoftBlock});
return addonFor(this).updateBlocklistState({applySoftBlock});
},
get userDisabled() {

View File

@ -1234,9 +1234,7 @@ this.XPIDatabaseReconcile = {
// If there isn't an updated install manifest for this add-on then load it.
if (!aNewAddon) {
let file = new nsIFile(aAddonState.path);
aNewAddon = syncLoadManifestFromFile(file, aInstallLocation);
aNewAddon.updateBlocklistState({oldAddon: aOldAddon});
aNewAddon = syncLoadManifestFromFile(file, aInstallLocation, aOldAddon);
}
// The ID in the manifest that was loaded must match the ID of the old
@ -1295,19 +1293,12 @@ this.XPIDatabaseReconcile = {
* ran
* @param aAddonState
* The new state of the add-on
* @param aOldAppVersion
* The version of the application last run with this profile or null
* if it is a new profile or the version is unknown
* @param aOldPlatformVersion
* The version of the platform last run with this profile or null
* if it is a new profile or the version is unknown
* @param aReloadMetadata
* A boolean which indicates whether metadata should be reloaded from
* the addon manifests. Default to false.
* @return the new addon.
*/
updateCompatibility(aInstallLocation, aOldAddon, aAddonState, aOldAppVersion,
aOldPlatformVersion, aReloadMetadata) {
updateCompatibility(aInstallLocation, aOldAddon, aAddonState, aReloadMetadata) {
logger.debug("Updating compatibility for add-on " + aOldAddon.id + " in " + aInstallLocation.name);
let checkSigning = aOldAddon.signedState === undefined && ADDON_SIGNING &&
@ -1346,7 +1337,6 @@ this.XPIDatabaseReconcile = {
copyProperties(manifest, props, aOldAddon);
}
aOldAddon.updateBlocklistState({updateDatabase: false});
aOldAddon.appDisabled = !isUsableAddon(aOldAddon);
return aOldAddon;
@ -1409,6 +1399,10 @@ this.XPIDatabaseReconcile = {
locationAddonMap.set(a.id, a);
}
// Keep track of add-ons whose blocklist status may have changed. We'll check this
// after everything else.
let addonsToCheckAgainstBlocklist = [];
// Build the list of current add-ons into similar maps. When add-ons are still
// present we re-use the add-on objects from the database and update their
// details directly
@ -1463,8 +1457,10 @@ this.XPIDatabaseReconcile = {
// version has changed. A schema change also reloads metadata from
// the manifests.
newAddon = this.updateCompatibility(installLocation, oldAddon, xpiState,
aOldAppVersion, aOldPlatformVersion,
aSchemaChange);
// We need to do a blocklist check later, but the add-on may have changed by then.
// Avoid storing the current copy and just get one when we need one instead.
addonsToCheckAgainstBlocklist.push(newAddon.id);
} else {
// No change
newAddon = oldAddon;
@ -1669,6 +1665,26 @@ this.XPIDatabaseReconcile = {
XPIDatabase.migrateData = null;
XPIDatabase.saveChanges();
// Do some blocklist checks. These will happen after we've just saved everything,
// because they're async and depend on the blocklist loading. When we're done, save
// the data if any of the add-ons' blocklist state has changed.
AddonManager.shutdown.addBlocker(
"Update add-on blocklist state into add-on DB",
(async () => {
// Avoid querying the AddonManager immediately to give startup a chance
// to complete.
await Promise.resolve();
let addons = await AddonManager.getAddonsByIDs(addonsToCheckAgainstBlocklist);
await Promise.all(addons.map(addon => {
if (addon) {
return addon.updateBlocklistState({updateDatabase: false});
}
return null;
}));
XPIDatabase.saveChanges();
})().catch(Cu.reportError)
);
return true;
},
};

View File

@ -344,9 +344,8 @@ Blocklist.prototype = {
return null;
},
getAddonBlocklistEntry(addon, appVersion, toolkitVersion) {
if (!this.isLoaded)
this._loadBlocklist();
async getAddonBlocklistEntry(addon, appVersion, toolkitVersion) {
await this.loadBlocklistAsync();
return this._getAddonBlocklistEntry(addon, this._addonEntries,
appVersion, toolkitVersion);
},
@ -766,9 +765,20 @@ Blocklist.prototype = {
this._addonEntries = null;
this._gfxEntries = null;
this._pluginEntries = null;
delete this._preloadPromise;
},
async loadBlocklistAsync() {
if (this.isLoaded) {
return;
}
if (!this._preloadPromise) {
this._preloadPromise = this._loadBlocklistAsyncInternal();
}
await this._preloadPromise;
},
async _loadBlocklistAsyncInternal() {
let profPath = OS.Path.join(OS.Constants.Path.profileDir, FILE_BLOCKLIST);
try {
await this._preloadBlocklistFile(profPath);
@ -789,8 +799,7 @@ Blocklist.prototype = {
},
async _preloadBlocklistFile(path) {
if (this._addonEntries) {
// The file has been already loaded.
if (this.isLoaded) {
return;
}
@ -1217,7 +1226,7 @@ Blocklist.prototype = {
Services.ppmm.broadcastAsyncMessage("Blocklist:blocklistInvalidated", {});
},
_blocklistUpdated(oldAddonEntries, oldPluginEntries) {
async _blocklistUpdated(oldAddonEntries, oldPluginEntries) {
var addonList = [];
// A helper function that reverts the prefs passed to default values.
@ -1226,178 +1235,177 @@ Blocklist.prototype = {
Services.prefs.clearUserPref(pref);
}
const types = ["extension", "theme", "locale", "dictionary", "service"];
AddonManager.getAddonsByTypes(types, addons => {
for (let addon of addons) {
let oldState = addon.blocklistState;
if (addon.updateBlocklistState) {
addon.updateBlocklistState(false);
} else if (oldAddonEntries) {
oldState = this._getAddonBlocklistState(addon, oldAddonEntries);
} else {
oldState = Ci.nsIBlocklistService.STATE_NOTBLOCKED;
let addons = await AddonManager.getAddonsByTypes(types);
for (let addon of addons) {
let oldState = addon.blocklistState;
if (addon.updateBlocklistState) {
await addon.updateBlocklistState(false);
} else if (oldAddonEntries) {
oldState = this._getAddonBlocklistState(addon, oldAddonEntries);
} else {
oldState = Ci.nsIBlocklistService.STATE_NOTBLOCKED;
}
let state = addon.blocklistState;
LOG("Blocklist state for " + addon.id + " changed from " +
oldState + " to " + state);
// We don't want to re-warn about add-ons
if (state == oldState)
continue;
if (state === Ci.nsIBlocklistService.STATE_BLOCKED) {
// It's a hard block. We must reset certain preferences.
let prefs = this._getAddonPrefs(addon);
resetPrefs(prefs);
}
// Ensure that softDisabled is false if the add-on is not soft blocked
if (state != Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
addon.softDisabled = false;
// Don't warn about add-ons becoming unblocked.
if (state == Ci.nsIBlocklistService.STATE_NOT_BLOCKED)
continue;
// If an add-on has dropped from hard to soft blocked just mark it as
// soft disabled and don't warn about it.
if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED &&
oldState == Ci.nsIBlocklistService.STATE_BLOCKED) {
addon.softDisabled = true;
continue;
}
// If the add-on is already disabled for some reason then don't warn
// about it
if (!addon.isActive) {
// But mark it as softblocked if necessary. Note that we avoid setting
// softDisabled at the same time as userDisabled to make it clear
// which was the original cause of the add-on becoming disabled in a
// way that the user can change.
if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED && !addon.userDisabled)
addon.softDisabled = true;
continue;
}
let entry = this._getAddonBlocklistEntry(addon, this._addonEntries);
addonList.push({
name: addon.name,
version: addon.version,
icon: addon.iconURL,
disable: false,
blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
item: addon,
url: entry && entry.url,
});
}
AddonManagerPrivate.updateAddonAppDisabledStates();
var phs = Cc["@mozilla.org/plugin/host;1"].
getService(Ci.nsIPluginHost);
var plugins = phs.getPluginTags();
for (let plugin of plugins) {
let oldState = -1;
if (oldPluginEntries)
oldState = this._getPluginBlocklistState(plugin, oldPluginEntries);
let state = this.getPluginBlocklistState(plugin);
LOG("Blocklist state for " + plugin.name + " changed from " +
oldState + " to " + state);
// We don't want to re-warn about items
if (state == oldState)
continue;
if (oldState == Ci.nsIBlocklistService.STATE_BLOCKED) {
if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
plugin.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
} else if (!plugin.disabled && state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
if (state != Ci.nsIBlocklistService.STATE_OUTDATED &&
state != Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE &&
state != Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
addonList.push({
name: plugin.name,
version: plugin.version,
icon: "chrome://mozapps/skin/plugins/pluginGeneric.svg",
disable: false,
blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
item: plugin,
url: this.getPluginBlocklistURL(plugin),
});
}
let state = addon.blocklistState;
}
}
LOG("Blocklist state for " + addon.id + " changed from " +
oldState + " to " + state);
if (addonList.length == 0) {
this._notifyObserversBlocklistUpdated();
return;
}
// We don't want to re-warn about add-ons
if (state == oldState)
if ("@mozilla.org/addons/blocklist-prompt;1" in Cc) {
try {
let blockedPrompter = Cc["@mozilla.org/addons/blocklist-prompt;1"]
.getService(Ci.nsIBlocklistPrompt);
blockedPrompter.prompt(addonList);
} catch (e) {
LOG(e);
}
this._notifyObserversBlocklistUpdated();
return;
}
var args = {
restart: false,
list: addonList
};
// This lets the dialog get the raw js object
args.wrappedJSObject = args;
/*
Some tests run without UI, so the async code listens to a message
that can be sent programatically
*/
let applyBlocklistChanges = () => {
for (let addon of addonList) {
if (!addon.disable)
continue;
if (state === Ci.nsIBlocklistService.STATE_BLOCKED) {
// It's a hard block. We must reset certain preferences.
let prefs = this._getAddonPrefs(addon);
if (addon.item instanceof Ci.nsIPluginTag)
addon.item.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
else {
// This add-on is softblocked.
addon.item.softDisabled = true;
// We must revert certain prefs.
let prefs = this._getAddonPrefs(addon.item);
resetPrefs(prefs);
}
// Ensure that softDisabled is false if the add-on is not soft blocked
if (state != Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
addon.softDisabled = false;
// Don't warn about add-ons becoming unblocked.
if (state == Ci.nsIBlocklistService.STATE_NOT_BLOCKED)
continue;
// If an add-on has dropped from hard to soft blocked just mark it as
// soft disabled and don't warn about it.
if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED &&
oldState == Ci.nsIBlocklistService.STATE_BLOCKED) {
addon.softDisabled = true;
continue;
}
// If the add-on is already disabled for some reason then don't warn
// about it
if (!addon.isActive) {
// But mark it as softblocked if necessary. Note that we avoid setting
// softDisabled at the same time as userDisabled to make it clear
// which was the original cause of the add-on becoming disabled in a
// way that the user can change.
if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED && !addon.userDisabled)
addon.softDisabled = true;
continue;
}
let entry = this._getAddonBlocklistEntry(addon, this._addonEntries);
addonList.push({
name: addon.name,
version: addon.version,
icon: addon.iconURL,
disable: false,
blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
item: addon,
url: entry && entry.url,
});
}
AddonManagerPrivate.updateAddonAppDisabledStates();
if (args.restart)
restartApp();
var phs = Cc["@mozilla.org/plugin/host;1"].
getService(Ci.nsIPluginHost);
var plugins = phs.getPluginTags();
this._notifyObserversBlocklistUpdated();
Services.obs.removeObserver(applyBlocklistChanges, "addon-blocklist-closed");
};
for (let plugin of plugins) {
let oldState = -1;
if (oldPluginEntries)
oldState = this._getPluginBlocklistState(plugin, oldPluginEntries);
let state = this.getPluginBlocklistState(plugin);
LOG("Blocklist state for " + plugin.name + " changed from " +
oldState + " to " + state);
// We don't want to re-warn about items
if (state == oldState)
continue;
Services.obs.addObserver(applyBlocklistChanges, "addon-blocklist-closed");
if (oldState == Ci.nsIBlocklistService.STATE_BLOCKED) {
if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
plugin.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
} else if (!plugin.disabled && state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
if (state != Ci.nsIBlocklistService.STATE_OUTDATED &&
state != Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE &&
state != Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
addonList.push({
name: plugin.name,
version: plugin.version,
icon: "chrome://mozapps/skin/plugins/pluginGeneric.svg",
disable: false,
blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
item: plugin,
url: this.getPluginBlocklistURL(plugin),
});
}
}
}
if (Services.prefs.getBoolPref(PREF_BLOCKLIST_SUPPRESSUI, false)) {
applyBlocklistChanges();
return;
}
if (addonList.length == 0) {
this._notifyObserversBlocklistUpdated();
return;
}
if ("@mozilla.org/addons/blocklist-prompt;1" in Cc) {
try {
let blockedPrompter = Cc["@mozilla.org/addons/blocklist-prompt;1"]
.getService(Ci.nsIBlocklistPrompt);
blockedPrompter.prompt(addonList);
} catch (e) {
LOG(e);
}
this._notifyObserversBlocklistUpdated();
return;
}
var args = {
restart: false,
list: addonList
};
// This lets the dialog get the raw js object
args.wrappedJSObject = args;
/*
Some tests run without UI, so the async code listens to a message
that can be sent programatically
*/
let applyBlocklistChanges = () => {
for (let addon of addonList) {
if (!addon.disable)
continue;
if (addon.item instanceof Ci.nsIPluginTag)
addon.item.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
else {
// This add-on is softblocked.
addon.item.softDisabled = true;
// We must revert certain prefs.
let prefs = this._getAddonPrefs(addon.item);
resetPrefs(prefs);
}
}
if (args.restart)
restartApp();
this._notifyObserversBlocklistUpdated();
Services.obs.removeObserver(applyBlocklistChanges, "addon-blocklist-closed");
};
Services.obs.addObserver(applyBlocklistChanges, "addon-blocklist-closed");
if (Services.prefs.getBoolPref(PREF_BLOCKLIST_SUPPRESSUI, false)) {
function blocklistUnloadHandler(event) {
if (event.target.location == URI_BLOCKLIST_DIALOG) {
applyBlocklistChanges();
return;
blocklistWindow.removeEventListener("unload", blocklistUnloadHandler);
}
}
function blocklistUnloadHandler(event) {
if (event.target.location == URI_BLOCKLIST_DIALOG) {
applyBlocklistChanges();
blocklistWindow.removeEventListener("unload", blocklistUnloadHandler);
}
}
let blocklistWindow = Services.ww.openWindow(null, URI_BLOCKLIST_DIALOG, "",
"chrome,centerscreen,dialog,titlebar", args);
if (blocklistWindow)
blocklistWindow.addEventListener("unload", blocklistUnloadHandler);
});
let blocklistWindow = Services.ww.openWindow(null, URI_BLOCKLIST_DIALOG, "",
"chrome,centerscreen,dialog,titlebar", args);
if (blocklistWindow)
blocklistWindow.addEventListener("unload", blocklistUnloadHandler);
},
classID: Components.ID("{66354bc9-7ed1-4692-ae1d-8da97d6b205e}"),

View File

@ -14,8 +14,8 @@ gTestserver.registerDirectory("/data/", do_get_file("data"));
const PREF_BLOCKLIST_ITEM_URL = "extensions.blocklist.itemURL";
Services.prefs.setCharPref(PREF_BLOCKLIST_ITEM_URL, "http://example.com/blocklist/%blockID%");
function getAddonBlocklistURL(addon) {
let entry = Services.blocklist.getAddonBlocklistEntry(addon);
async function getAddonBlocklistURL(addon) {
let entry = await Services.blocklist.getAddonBlocklistEntry(addon);
return entry && entry.url;
}
@ -366,11 +366,11 @@ add_task(async function test_pt3() {
checkAddonState(addons[3], {userDisabled: false, softDisabled: false, appDisabled: true});
// Check blockIDs are correct
equal(getAddonBlocklistURL(addons[0]), create_blocklistURL(addons[0].id));
equal(getAddonBlocklistURL(addons[1]), create_blocklistURL(addons[1].id));
equal(getAddonBlocklistURL(addons[2]), create_blocklistURL(addons[2].id));
equal(getAddonBlocklistURL(addons[3]), create_blocklistURL(addons[3].id));
equal(getAddonBlocklistURL(addons[4]), create_blocklistURL(addons[4].id));
equal(await getAddonBlocklistURL(addons[0]), create_blocklistURL(addons[0].id));
equal(await getAddonBlocklistURL(addons[1]), create_blocklistURL(addons[1].id));
equal(await getAddonBlocklistURL(addons[2]), create_blocklistURL(addons[2].id));
equal(await getAddonBlocklistURL(addons[3]), create_blocklistURL(addons[3].id));
equal(await getAddonBlocklistURL(addons[4]), create_blocklistURL(addons[4].id));
// All plugins have the same blockID on the test
equal(Services.blocklist.getPluginBlocklistURL(PLUGINS[0]), create_blocklistURL("test_bug455906_plugin"));

View File

@ -804,7 +804,7 @@ add_task(async function update_schema_2() {
await changeXPIDBVersion(100);
gAppInfo.version = "2";
startupManager(true);
await promiseStartupManager(true);
let [s1, s2, s3, s4, h, r] = await promiseAddonsByIDs(ADDON_IDS);
@ -828,7 +828,7 @@ add_task(async function update_schema_3() {
await promiseShutdownManager();
await changeXPIDBVersion(100);
gAppInfo.version = "2.5";
startupManager(true);
await promiseStartupManager(true);
let [s1, s2, s3, s4, h, r] = await promiseAddonsByIDs(ADDON_IDS);
@ -861,7 +861,7 @@ add_task(async function update_schema_5() {
await changeXPIDBVersion(100);
gAppInfo.version = "1";
startupManager(true);
await promiseStartupManager(true);
let [s1, s2, s3, s4, h, r] = await promiseAddonsByIDs(ADDON_IDS);
@ -1062,7 +1062,7 @@ add_task(async function run_addon_change_2_test() {
getFileForAddon(profileDir, hardblock_1.id).remove(true);
getFileForAddon(profileDir, regexpblock_1.id).remove(true);
startupManager(false);
await promiseStartupManager(false);
await promiseShutdownManager();
writeInstallRDFForExtension(softblock1_2, profileDir);
@ -1188,7 +1188,7 @@ add_task(async function run_background_update_2_test() {
getFileForAddon(profileDir, hardblock_1.id).remove(true);
getFileForAddon(profileDir, regexpblock_1.id).remove(true);
startupManager(false);
await promiseStartupManager(false);
await promiseShutdownManager();
writeInstallRDFForExtension(softblock1_3, profileDir);
@ -1294,7 +1294,7 @@ add_task(async function run_manual_update_2_test() {
getFileForAddon(profileDir, hardblock_1.id).remove(true);
getFileForAddon(profileDir, regexpblock_1.id).remove(true);
startupManager(false);
await promiseStartupManager(false);
await promiseShutdownManager();
writeInstallRDFForExtension(softblock1_1, profileDir);

View File

@ -64,9 +64,10 @@ interface nsIBlocklistService : nsISupports
[optional] in AString toolkitVersion);
/**
* Returns the blocklist entry, as an object with `state` and `url`
* Returns a promise that resolves to the blocklist entry.
* The blocklist entry is an object with `state` and `url`
* properties, if a blocklist entry for the add-on exists, or null
* othereise.
* otherwise.
* @param addon
* The addon object to match.