mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Bug 1452618 - make getAddonBlocklistEntry asynchronous, r=kmag
MozReview-Commit-ID: 4Kpx7M57404 --HG-- extra : rebase_source : 6c5a242b40288703fb424e81ea701eeba3c71a27
This commit is contained in:
parent
a7f6ba42a1
commit
95b991b77b
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
},
|
||||
};
|
||||
|
@ -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}"),
|
||||
|
@ -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"));
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user