--- a/devtools/client/aboutdebugging/test/head.js
+++ b/devtools/client/aboutdebugging/test/head.js
@@ -446,19 +446,17 @@ function installAddonWithManager(filePat
onInstallCancelled: reject,
onInstallEnded: resolve
});
install.install();
});
}
function getAddonByID(addonId) {
- return new Promise(resolve => {
- AddonManager.getAddonByID(addonId, addon => resolve(addon));
- });
+ return AddonManager.getAddonByID(addonId);
}
/**
* Uninstall an add-on.
*/
async function tearDownAddon(addon) {
const onUninstalled = promiseAddonEvent("onUninstalled");
addon.uninstall();
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -246,18 +246,18 @@ function createMockAddonProvider(aName)
return aName;
},
addAddon(aAddon) {
this._addons.push(aAddon);
AddonManagerPrivate.callAddonListeners("onInstalled", new MockAddonWrapper(aAddon));
},
- getAddonsByTypes(aTypes, aCallback) {
- aCallback(this._addons.map(a => new MockAddonWrapper(a)));
+ async getAddonsByTypes(aTypes) {
+ return this._addons.map(a => new MockAddonWrapper(a));
},
shutdown() {
return Promise.resolve();
},
};
return mockProvider;
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -247,61 +247,37 @@ function callProvider(aProvider, aMethod
reportProviderError(aProvider, aMethod, e);
return aDefault;
}
}
/**
* Calls a method on a provider if it exists and consumes any thrown exception.
* Parameters after aMethod are passed to aProvider.aMethod().
- * The last parameter must be a callback function.
* If the provider does not implement the method, or the method throws, calls
* the callback with 'undefined'.
*
* @param aProvider
* The provider to call
* @param aMethod
* The method name to call
*/
-function callProviderAsync(aProvider, aMethod, ...aArgs) {
- let callback = aArgs[aArgs.length - 1];
+async function promiseCallProvider(aProvider, aMethod, ...aArgs) {
if (!(aMethod in aProvider)) {
- callback(undefined);
return undefined;
}
try {
return aProvider[aMethod].apply(aProvider, aArgs);
} catch (e) {
reportProviderError(aProvider, aMethod, e);
- callback(undefined);
return undefined;
}
}
/**
- * Calls a method on a provider if it exists and consumes any thrown exception.
- * Parameters after aMethod are passed to aProvider.aMethod() and an additional
- * callback is added for the provider to return a result to.
- *
- * @param aProvider
- * The provider to call
- * @param aMethod
- * The method name to call
- * @return {Promise}
- * @resolves The result the provider returns, or |undefined| if the provider
- * does not implement the method or the method throws.
- * @rejects Never
- */
-function promiseCallProvider(aProvider, aMethod, ...aArgs) {
- return new Promise(resolve => {
- callProviderAsync(aProvider, aMethod, ...aArgs, resolve);
- });
-}
-
-/**
* Gets the currently selected locale for display.
* @return the selected locale or "en-US" if none is selected
*/
function getLocale() {
return Services.locale.getRequestedLocale() || "en-US";
}
function webAPIForAddon(addon) {
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -416,50 +416,43 @@ var LightweightThemeManager = {
}
},
/**
* Called to get an Addon with a particular ID.
*
* @param aId
* The ID of the add-on to retrieve
- * @param aCallback
- * A callback to pass the Addon to
*/
- getAddonByID(aId, aCallback) {
+ async getAddonByID(aId) {
let id = _getInternalID(aId);
if (!id) {
- aCallback(null);
- return;
+ return null;
}
let theme = this.getUsedTheme(id);
if (!theme) {
- aCallback(null);
- return;
+ return null;
}
- aCallback(new AddonWrapper(theme));
+ return new AddonWrapper(theme);
},
/**
* Called to get Addons of a particular type.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types.
- * @param aCallback
- * A callback to pass an array of Addons to
*/
- getAddonsByTypes(aTypes, aCallback) {
+ getAddonsByTypes(aTypes) {
if (aTypes && !aTypes.includes(ADDON_TYPE)) {
- aCallback([]);
- return;
+ return [];
}
- aCallback(this.usedThemes.map(a => new AddonWrapper(a)));
+ return this.usedThemes.map(a => new AddonWrapper(a));
},
};
const wrapperMap = new WeakMap();
let themeFor = wrapper => wrapperMap.get(wrapper);
/**
* The AddonWrapper wraps lightweight theme to provide the data visible to
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -1047,17 +1047,17 @@
isLegacyExtension(this.mAddon);
this.setAttribute("legacy", legacyWarning);
document.getAnonymousElementByAttribute(this, "anonid", "legacy").href = SUPPORT_URL + "webextensions";
if (!("applyBackgroundUpdates" in this.mAddon) ||
(this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE ||
(this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
!AddonManager.autoUpdateDefault))) {
- AddonManager.getAllInstalls(aInstallsList => {
+ AddonManager.getAllInstalls().then(aInstallsList => {
// This can return after the binding has been destroyed,
// so try to detect that and return early
if (!("onNewInstall" in this))
return;
for (let install of aInstallsList) {
if (install.existingAddon &&
install.existingAddon.id == this.mAddon.id &&
install.state == AddonManager.STATE_AVAILABLE) {
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -620,42 +620,40 @@ var GMPProvider = {
if (!shutdownSucceeded) {
throw new Error("Shutdown failed");
}
})();
return shutdownTask;
},
- getAddonByID(aId, aCallback) {
+ async getAddonByID(aId) {
if (!this.isEnabled) {
- aCallback(null);
- return;
+ return null;
}
let plugin = this._plugins.get(aId);
if (plugin && !GMPUtils.isPluginHidden(plugin)) {
- aCallback(plugin.wrapper);
+ return plugin.wrapper;
} else {
- aCallback(null);
+ return null;
}
},
- getAddonsByTypes(aTypes, aCallback) {
+ async getAddonsByTypes(aTypes) {
if (!this.isEnabled ||
(aTypes && !aTypes.includes("plugin"))) {
- aCallback([]);
- return;
+ return [];
}
let results = Array.from(this._plugins.values())
.filter(p => !GMPUtils.isPluginHidden(p))
.map(p => p.wrapper);
- aCallback(results);
+ return results;
},
get isEnabled() {
return GMPPrefs.getBool(GMPPrefs.KEY_PROVIDER_ENABLED, false);
},
buildPluginList() {
this._plugins = new Map();
--- a/toolkit/mozapps/extensions/internal/PluginProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/PluginProvider.jsm
@@ -87,76 +87,62 @@ var PluginProvider = {
aPlugin.tags);
},
/**
* Called to get an Addon with a particular ID.
*
* @param aId
* The ID of the add-on to retrieve
- * @param aCallback
- * A callback to pass the Addon to
*/
- getAddonByID(aId, aCallback) {
+ async getAddonByID(aId) {
if (!this.plugins)
this.buildPluginList();
if (aId in this.plugins)
- aCallback(this.buildWrapper(this.plugins[aId]));
- else
- aCallback(null);
+ return this.buildWrapper(this.plugins[aId]);
+ return null;
},
/**
* Called to get Addons of a particular type.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types.
- * @param callback
- * A callback to pass an array of Addons to
*/
- getAddonsByTypes(aTypes, aCallback) {
+ async getAddonsByTypes(aTypes) {
if (aTypes && !aTypes.includes("plugin")) {
- aCallback([]);
- return;
+ return [];
}
if (!this.plugins)
this.buildPluginList();
- let results = [];
-
- for (let id in this.plugins)
- this.getAddonByID(id, (addon) => results.push(addon));
-
- aCallback(results);
+ return Promise.all(Object.keys(this.plugins).map(
+ id => this.getAddonByID(id)));
},
/**
* Called to get Addons that have pending operations.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types
- * @param aCallback
- * A callback to pass an array of Addons to
*/
- getAddonsWithOperationsByTypes(aTypes, aCallback) {
- aCallback([]);
+ async getAddonsWithOperationsByTypes(aTypes) {
+ return [];
},
/**
* Called to get the current AddonInstalls, optionally restricting by type.
*
* @param aTypes
* An array of types or null to get all types
- * @param aCallback
- * A callback to pass the array of AddonInstalls to
*/
- getInstallsByTypes(aTypes, aCallback) {
- aCallback([]);
+ getInstallsByTypes(aTypes) {
+ return [];
},
/**
* Builds a list of the current plugins reported by the plugin host
*
* @return a dictionary of plugins indexed by our generated ID
*/
getPluginList() {
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -2449,22 +2449,16 @@ var XPIProvider = {
logger.info("No system add-ons list was returned.");
await systemAddonLocation.cleanDirectories();
return;
}
let addonList = new Map(
res.gmpAddons.map(spec => [spec.id, { spec, path: null, addon: null }]));
- let getAddonsInLocation = (location) => {
- return new Promise(resolve => {
- XPIDatabase.getAddonsInLocation(location, resolve);
- });
- };
-
let setMatches = (wanted, existing) => {
if (wanted.size != existing.size)
return false;
for (let [id, addon] of existing) {
let wantedInfo = wanted.get(id);
if (!wantedInfo)
@@ -2472,26 +2466,26 @@ var XPIProvider = {
if (wantedInfo.spec.version != addon.version)
return false;
}
return true;
};
// If this matches the current set in the profile location then do nothing.
- let updatedAddons = addonMap(await getAddonsInLocation(KEY_APP_SYSTEM_ADDONS));
+ let updatedAddons = addonMap(await XPIDatabase.getAddonsInLocation(KEY_APP_SYSTEM_ADDONS));
if (setMatches(addonList, updatedAddons)) {
logger.info("Retaining existing updated system add-ons.");
await systemAddonLocation.cleanDirectories();
return;
}
// If this matches the current set in the default location then reset the
// updated set.
- let defaultAddons = addonMap(await getAddonsInLocation(KEY_APP_SYSTEM_DEFAULTS));
+ let defaultAddons = addonMap(await XPIDatabase.getAddonsInLocation(KEY_APP_SYSTEM_DEFAULTS));
if (setMatches(addonList, defaultAddons)) {
logger.info("Resetting system add-ons.");
systemAddonLocation.resetAddonSet();
await systemAddonLocation.cleanDirectories();
return;
}
// Download all the add-ons
@@ -3163,53 +3157,48 @@ var XPIProvider = {
* @param aName
* A name for the install
* @param aIcons
* Icon URLs for the install
* @param aVersion
* A version for the install
* @param aBrowser
* The browser performing the install
- * @param aCallback
- * A callback to pass the AddonInstall to
*/
- getInstallForURL(aUrl, aHash, aName, aIcons, aVersion, aBrowser,
- aCallback) {
+ async getInstallForURL(aUrl, aHash, aName, aIcons, aVersion, aBrowser) {
let location = XPIProvider.installLocationsByName[KEY_APP_PROFILE];
let url = Services.io.newURI(aUrl);
let options = {
hash: aHash,
browser: aBrowser,
name: aName,
icons: aIcons,
version: aVersion,
};
if (url instanceof Ci.nsIFileURL) {
let install = new LocalAddonInstall(location, url, options);
- install.init().then(() => { aCallback(install.wrapper); });
- } else {
- let install = new DownloadAddonInstall(location, url, options);
- aCallback(install.wrapper);
- }
+ await install.init();
+ return install.wrapper;
+ }
+
+ let install = new DownloadAddonInstall(location, url, options);
+ return install.wrapper;
},
/**
* Called to get an AddonInstall to install an add-on from a local file.
*
* @param aFile
* The file to be installed
- * @param aCallback
- * A callback to pass the AddonInstall to
*/
- getInstallForFile(aFile, aCallback) {
- createLocalInstall(aFile).then(install => {
- aCallback(install ? install.wrapper : null);
- });
+ async getInstallForFile(aFile) {
+ let install = await createLocalInstall(aFile);
+ return install ? install.wrapper : null;
},
/**
* Temporarily installs add-on from a local XPI file or directory.
* As this is intended for development, the signature is not checked and
* the add-on does not persist on application restart.
*
* @param aFile
@@ -3273,18 +3262,17 @@ var XPIProvider = {
throw new Error(message);
}
if (!addon.bootstrap) {
throw new Error("Only restartless (bootstrap) add-ons"
+ " can be installed from sources:", addon.id);
}
let installReason = BOOTSTRAP_REASONS.ADDON_INSTALL;
- let oldAddon = await new Promise(
- resolve => XPIDatabase.getVisibleAddonForID(addon.id, resolve));
+ let oldAddon = await XPIDatabase.getVisibleAddonForID(addon.id);
let callUpdate = false;
let extraParams = {};
extraParams.temporarilyInstalled = aInstallLocation === TemporaryInstallLocation;
if (oldAddon) {
if (!oldAddon.bootstrap) {
logger.warn("Non-restartless Add-on is already installed", addon.id);
throw new Error("Non-restartless add-on with ID "
@@ -3390,17 +3378,17 @@ var XPIProvider = {
*/
getAddonByInstanceID(aInstanceID) {
if (!aInstanceID || typeof aInstanceID != "symbol")
throw Components.Exception("aInstanceID must be a Symbol()",
Cr.NS_ERROR_INVALID_ARG);
for (let [id, val] of this.activeAddons) {
if (aInstanceID == val.instanceID) {
- return new Promise(resolve => this.getAddonByID(id, resolve));
+ return this.getAddonByID(id);
}
}
return Promise.resolve(null);
},
/**
* Removes an AddonInstall from the list of active installs.
@@ -3412,67 +3400,59 @@ var XPIProvider = {
this.installs.delete(aInstall);
},
/**
* Called to get an Addon with a particular ID.
*
* @param aId
* The ID of the add-on to retrieve
- * @param aCallback
- * A callback to pass the Addon to
*/
- async getAddonByID(aId, aCallback) {
+ async getAddonByID(aId) {
let aAddon = await XPIDatabase.getVisibleAddonForID(aId);
- aCallback(aAddon ? aAddon.wrapper : null);
+ return aAddon ? aAddon.wrapper : null;
},
/**
* Called to get Addons of a particular type.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types.
- * @param aCallback
- * A callback to pass an array of Addons to
*/
- async getAddonsByTypes(aTypes, aCallback) {
+ async getAddonsByTypes(aTypes) {
let typesToGet = getAllAliasesForTypes(aTypes);
if (typesToGet && !typesToGet.some(type => ALL_EXTERNAL_TYPES.has(type))) {
- aCallback([]);
- return;
- }
-
- let aAddons = await XPIDatabase.getVisibleAddons(typesToGet);
- aCallback(aAddons.map(a => a.wrapper));
+ return [];
+ }
+
+ let addons = await XPIDatabase.getVisibleAddons(typesToGet);
+ return addons.map(a => a.wrapper);
},
/**
* Called to get active Addons of a particular type
*
* @param aTypes
* An array of types to fetch. Can be null to get all types.
* @returns {Promise<Array<Addon>>}
*/
- getActiveAddons(aTypes) {
+ async getActiveAddons(aTypes) {
// If we already have the database loaded, returning full info is fast.
if (this.isDBLoaded) {
- return new Promise(resolve => {
- this.getAddonsByTypes(aTypes, addons => {
- resolve({
- addons: addons.filter(addon => addon.isActive),
- fullData: true,
- });
- });
- });
+ let addons = await this.getAddonsByTypes(aTypes);
+ return {
+ addons: addons.filter(addon => addon.isActive),
+ fullData: true,
+ };
}
// Construct addon-like objects with the information we already
// have in memory.
if (!XPIStates.db) {
- return Promise.reject(new Error("XPIStates not yet initialized"));
+ throw new Error("XPIStates not yet initialized");
}
let result = [];
for (let addon of XPIStates.enabledAddons()) {
if (aTypes && !aTypes.includes(addon.type)) {
continue;
}
let location = this.installLocationsByName[addon.location.name];
@@ -3486,72 +3466,66 @@ var XPIProvider = {
type: addon.type,
updateDate: addon.lastModifiedTime,
scope,
isSystem,
isWebExtension: isWebExtension(addon),
});
}
- return Promise.resolve({addons: result, fullData: false});
+ return {addons: result, fullData: false};
},
/**
* Obtain an Addon having the specified Sync GUID.
*
* @param aGUID
* String GUID of add-on to retrieve
- * @param aCallback
- * A callback to pass the Addon to. Receives null if not found.
*/
- async getAddonBySyncGUID(aGUID, aCallback) {
- let aAddon = await XPIDatabase.getAddonBySyncGUID(aGUID);
- aCallback(aAddon ? aAddon.wrapper : null);
+ async getAddonBySyncGUID(aGUID) {
+ let addon = await XPIDatabase.getAddonBySyncGUID(aGUID);
+ return addon ? addon.wrapper : null;
},
/**
* Called to get Addons that have pending operations.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types
- * @param aCallback
- * A callback to pass an array of Addons to
*/
- async getAddonsWithOperationsByTypes(aTypes, aCallback) {
+ async getAddonsWithOperationsByTypes(aTypes) {
let typesToGet = getAllAliasesForTypes(aTypes);
let aAddons = await XPIDatabase.getVisibleAddonsWithPendingOperations(typesToGet);
let results = aAddons.map(a => a.wrapper);
for (let install of XPIProvider.installs) {
if (install.state == AddonManager.STATE_INSTALLED &&
!(install.addon.inDatabase))
results.push(install.addon.wrapper);
}
- aCallback(results);
+ return results;
},
/**
* Called to get the current AddonInstalls, optionally limiting to a list of
* types.
*
* @param aTypes
* An array of types or null to get all types
- * @param aCallback
- * A callback to pass the array of AddonInstalls to
*/
- getInstallsByTypes(aTypes, aCallback) {
+ getInstallsByTypes(aTypes) {
let results = [...this.installs];
if (aTypes) {
results = results.filter(install => {
return aTypes.includes(getExternalType(install.type));
});
}
- aCallback(results.map(install => install.wrapper));
+ return results.map(install => install.wrapper);
},
/**
* Called when a new add-on has been enabled when only one add-on of that type
* can be enabled.
*
* @param aId
* The ID of the newly enabled add-on
@@ -3580,45 +3554,29 @@ var XPIProvider = {
let addons = XPIDatabase.getAddons();
for (let addon of addons) {
this.updateAddonDisabledState(addon);
}
},
/**
* Update the repositoryAddon property for all add-ons.
- *
- * @param aCallback
- * Function to call when operation is complete.
*/
- async updateAddonRepositoryData(aCallback) {
- let aAddons = await XPIDatabase.getVisibleAddons(null);
- let pending = aAddons.length;
- logger.debug("updateAddonRepositoryData found " + pending + " visible add-ons");
- if (pending == 0) {
- aCallback();
- return;
- }
-
- function notifyComplete() {
- if (--pending == 0)
- aCallback();
- }
-
- for (let addon of aAddons) {
+ async updateAddonRepositoryData() {
+ let addons = await XPIDatabase.getVisibleAddons(null);
+ logger.debug("updateAddonRepositoryData found " + addons.length + " visible add-ons");
+
+ await Promise.all(addons.map(addon =>
AddonRepository.getCachedAddonByID(addon.id).then(aRepoAddon => {
if (aRepoAddon || AddonRepository.getCompatibilityOverridesSync(addon.id)) {
logger.debug("updateAddonRepositoryData got info for " + addon.id);
addon._repositoryAddon = aRepoAddon;
this.updateAddonDisabledState(addon);
}
-
- notifyComplete();
- });
- }
+ })));
},
onDebugConnectionChange({what, connection}) {
if (what != "opened")
return;
for (let [id, val] of this.activeAddons) {
connection.setAddonOptions(
@@ -6054,17 +6012,17 @@ class SystemAddonInstallLocation extends
// Make sure the base dir exists
await OS.File.makeDir(this._baseDir.path, { ignoreExisting: true });
let addonSet = SystemAddonInstallLocation._loadAddonSet();
// Remove any add-ons that are no longer part of the set.
for (let addonID of Object.keys(addonSet.addons)) {
if (!aAddons.includes(addonID)) {
- AddonManager.getAddonByID(addonID, a => a.uninstall());
+ AddonManager.getAddonByID(addonID).then(a => a.uninstall());
}
}
let newDir = this._baseDir.clone();
let uuidGen = Cc["@mozilla.org/uuid-generator;1"].
getService(Ci.nsIUUIDGenerator);
newDir.append("blank");
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -1221,17 +1221,17 @@ Blocklist.prototype = {
var addonList = [];
// A helper function that reverts the prefs passed to default values.
function resetPrefs(prefs) {
for (let pref of prefs)
Services.prefs.clearUserPref(pref);
}
const types = ["extension", "theme", "locale", "dictionary", "service"];
- AddonManager.getAddonsByTypes(types, addons => {
+ AddonManager.getAddonsByTypes(types).then(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;
--- a/toolkit/mozapps/extensions/test/AddonManagerTesting.jsm
+++ b/toolkit/mozapps/extensions/test/AddonManagerTesting.jsm
@@ -19,17 +19,17 @@ ChromeUtils.defineModuleGetter(this, "Ad
var AddonManagerTesting = {
/**
* Get the add-on that is specified by its ID.
*
* @return {Promise<Object>} A promise that resolves returning the found addon or null
* if it is not found.
*/
getAddonById(id) {
- return new Promise(resolve => AddonManager.getAddonByID(id, addon => resolve(addon)));
+ return AddonManager.getAddonByID(id);
},
/**
* Uninstall an add-on that is specified by its ID.
*
* The returned promise resolves on successful uninstall and rejects
* if the add-on is not unknown.
*
--- a/toolkit/mozapps/extensions/test/browser/browser_legacy.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_legacy.js
@@ -179,16 +179,18 @@ add_task(async function() {
// Disable unsigned extensions
SpecialPowers.pushPrefEnv({
set: [
["xpinstall.signatures.required", false],
],
});
+ await new Promise(executeSoon);
+
// The name of the pane should go back to "Legacy Extensions"
await mgrWin.gLegacyView.refreshVisibility();
is(catItem.disabled, false, "Legacy category is visible");
is(catItem.getAttribute("name"), get_string("type.legacy.name"),
"Category label with no unsigned extensions is correct");
// The unsigned extension should be present in the main extensions pane
await catUtils.openType("extension");
--- a/toolkit/mozapps/extensions/test/browser/browser_newaddon.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_newaddon.js
@@ -84,22 +84,28 @@ add_test(function() {
is_element_hidden(doc.getElementById("location"), "Should be no location displayed");
is(doc.getElementById("buttonDeck").selectedPanel, doc.getElementById("continuePanel"),
"Should be showing the right buttons");
let aAddon = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
ok(aAddon.seen, "Add-on should have been marked as seen");
+ await new Promise(executeSoon);
+
EventUtils.synthesizeMouseAtCenter(doc.getElementById("allow"),
{}, aTab.linkedBrowser.contentWindow);
+ await new Promise(executeSoon);
+
EventUtils.synthesizeMouseAtCenter(doc.getElementById("continue-button"),
{}, aTab.linkedBrowser.contentWindow);
+ await new Promise(executeSoon);
+
is(gBrowser.tabs.length, 1, "Page should have been closed");
ok(!aAddon.userDisabled, "Add-on should now have been enabled");
ok(aAddon.isActive, "Add-on should now be running");
aAddon.userDisabled = true;
aAddon.seen = false;
@@ -118,19 +124,23 @@ add_test(function() {
is_element_hidden(doc.getElementById("location"), "Should be no location displayed");
is(doc.getElementById("buttonDeck").selectedPanel, doc.getElementById("continuePanel"),
"Should be showing the right buttons");
let aAddon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
ok(aAddon.seen, "Add-on should have been marked as seen");
+ await new Promise(executeSoon);
+
EventUtils.synthesizeMouseAtCenter(doc.getElementById("continue-button"),
{}, aTab.linkedBrowser.contentWindow);
+ await new Promise(executeSoon);
+
is(gBrowser.tabs.length, 1, "Page should have been closed");
ok(aAddon.userDisabled, "Add-on should not have been enabled");
ok(!aAddon.isActive, "Add-on should not be running");
aAddon.seen = false;
run_next_test();
@@ -148,22 +158,28 @@ add_test(function() {
is_element_hidden(doc.getElementById("location"), "Should be no location displayed");
is(doc.getElementById("buttonDeck").selectedPanel, doc.getElementById("continuePanel"),
"Should be showing the right buttons");
let aAddon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
ok(aAddon.seen, "Add-on should have been marked as seen");
+ await new Promise(executeSoon);
+
EventUtils.synthesizeMouseAtCenter(doc.getElementById("allow"),
{}, aTab.linkedBrowser.contentWindow);
+ await new Promise(executeSoon);
+
EventUtils.synthesizeMouseAtCenter(doc.getElementById("continue-button"),
{}, aTab.linkedBrowser.contentWindow);
+ await new Promise(executeSoon);
+
is(doc.getElementById("buttonDeck").selectedPanel, doc.getElementById("restartPanel"),
"Should be showing the right buttons");
ok(!aAddon.userDisabled, "Add-on should now have been enabled");
ok(!aAddon.isActive, "Add-on should not be running");
ok(doc.getElementById("allow").disabled, "Should have disabled checkbox");
--- a/toolkit/mozapps/extensions/test/browser/browser_plugin_enabled_state_locked.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_plugin_enabled_state_locked.js
@@ -22,19 +22,17 @@ function getTestPluginPref() {
}
registerCleanupFunction(() => {
Services.prefs.unlockPref(getTestPluginPref());
Services.prefs.clearUserPref(getTestPluginPref());
});
function getPlugins() {
- return new Promise(resolve => {
- AddonManager.getAddonsByTypes(["plugin"], plugins => resolve(plugins));
- });
+ return AddonManager.getAddonsByTypes(["plugin"]);
}
function getTestPlugin(aPlugins) {
let testPluginId;
for (let plugin of aPlugins) {
if (plugin.name == "Test Plug-in") {
testPluginId = plugin.id;
--- a/toolkit/mozapps/extensions/test/browser/browser_pluginprefs.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_pluginprefs.js
@@ -37,28 +37,28 @@ add_test(async function() {
pluginEl.parentNode.ensureElementIsVisible(pluginEl);
let button = gManagerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "preferences-btn");
is_element_visible(button, "Preferences button should be visible");
button = gManagerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "details-btn");
EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
- Services.obs.addObserver(function observer(subject, topic, data) {
+ Services.obs.addObserver(async function observer(subject, topic, data) {
Services.obs.removeObserver(observer, topic);
// Wait for PluginProvider to do its stuff.
- executeSoon(function() {
- let doc = gManagerWindow.document.getElementById("addon-options").contentDocument;
+ await new Promise(executeSoon);
+
+ let doc = gManagerWindow.document.getElementById("addon-options").contentDocument;
- let pluginLibraries = doc.getElementById("pluginLibraries");
- ok(pluginLibraries, "Plugin file name row should be displayed");
- // the file name depends on the platform
- ok(pluginLibraries.textContent, testPlugin.pluginLibraries, "Plugin file name should be displayed");
+ let pluginLibraries = doc.getElementById("pluginLibraries");
+ ok(pluginLibraries, "Plugin file name row should be displayed");
+ // the file name depends on the platform
+ is(pluginLibraries.textContent, testPlugin.pluginLibraries, "Plugin file name should be displayed");
- let pluginMimeTypes = doc.getElementById("pluginMimeTypes");
- ok(pluginMimeTypes, "Plugin mime type row should be displayed");
- ok(pluginMimeTypes.textContent, "application/x-test (tst)", "Plugin mime type should be displayed");
+ let pluginMimeTypes = doc.getElementById("pluginMimeTypes");
+ ok(pluginMimeTypes, "Plugin mime type row should be displayed");
+ is(pluginMimeTypes.textContent, "application/x-test (tst)", "Plugin mime type should be displayed");
- run_next_test();
- });
+ run_next_test();
}, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED);
});
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -888,84 +888,75 @@ MockProvider.prototype = {
this.started = false;
},
/**
* Called to get an Addon with a particular ID.
*
* @param aId
* The ID of the add-on to retrieve
- * @param aCallback
- * A callback to pass the Addon to
*/
- getAddonByID: function MP_getAddon(aId, aCallback) {
+ async getAddonByID(aId) {
for (let addon of this.addons) {
if (addon.id == aId) {
- this._delayCallback(aCallback, addon);
- return;
+ return addon;
}
}
- aCallback(null);
+ return null;
},
/**
* Called to get Addons of a particular type.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types.
- * @param callback
- * A callback to pass an array of Addons to
*/
- getAddonsByTypes: function MP_getAddonsByTypes(aTypes, aCallback) {
+ async getAddonsByTypes(aTypes) {
var addons = this.addons.filter(function(aAddon) {
if (aTypes && aTypes.length > 0 && !aTypes.includes(aAddon.type))
return false;
return true;
});
- this._delayCallback(aCallback, addons);
+ return addons;
},
/**
* Called to get Addons that have pending operations.
*
* @param aTypes
* An array of types to fetch. Can be null to get all types
- * @param aCallback
- * A callback to pass an array of Addons to
*/
- getAddonsWithOperationsByTypes: function MP_getAddonsWithOperationsByTypes(aTypes, aCallback) {
+ async getAddonsWithOperationsByTypes(aTypes, aCallback) {
var addons = this.addons.filter(function(aAddon) {
if (aTypes && aTypes.length > 0 && !aTypes.includes(aAddon.type))
return false;
return aAddon.pendingOperations != 0;
});
- this._delayCallback(aCallback, addons);
+ return addons;
},
/**
* Called to get the current AddonInstalls, optionally restricting by type.
*
* @param aTypes
* An array of types or null to get all types
- * @param aCallback
- * A callback to pass the array of AddonInstalls to
*/
- getInstallsByTypes: function MP_getInstallsByTypes(aTypes, aCallback) {
+ async getInstallsByTypes(aTypes) {
var installs = this.installs.filter(function(aInstall) {
// Appear to have actually removed cancelled installs from the provider
if (aInstall.state == AddonManager.STATE_CANCELLED)
return false;
if (aTypes && aTypes.length > 0 && !aTypes.includes(aInstall.type))
return false;
return true;
});
- this._delayCallback(aCallback, installs);
+ return installs;
},
/**
* Called when a new add-on has been enabled when only one add-on of that type
* can be enabled.
*
* @param aId
* The ID of the newly enabled add-on
@@ -996,33 +987,29 @@ MockProvider.prototype = {
* @param aName
* A name for the install
* @param aIconURL
* An icon URL for the install
* @param aVersion
* A version for the install
* @param aLoadGroup
* An nsILoadGroup to associate requests with
- * @param aCallback
- * A callback to pass the AddonInstall to
*/
getInstallForURL: function MP_getInstallForURL(aUrl, aHash, aName, aIconURL,
- aVersion, aLoadGroup, aCallback) {
+ aVersion, aLoadGroup) {
// Not yet implemented
},
/**
* Called to get an AddonInstall to install an add-on from a local file.
*
* @param aFile
* The file to be installed
- * @param aCallback
- * A callback to pass the AddonInstall to
*/
- getInstallForFile: function MP_getInstallForFile(aFile, aCallback) {
+ getInstallForFile: function MP_getInstallForFile(aFile) {
// Not yet implemented
},
/**
* Called to test whether installing add-ons is enabled.
*
* @return true if installing is enabled
*/
@@ -1047,52 +1034,16 @@ MockProvider.prototype = {
*
* @param aUri
* The URI being installed from
* @return true if installing is allowed
*/
isInstallAllowed: function MP_isInstallAllowed(aUri) {
return false;
},
-
-
- /** *** Internal functions *****/
-
- /**
- * Delay calling a callback to fake a time-consuming async operation.
- * The delay is specified by the apiDelay property, in milliseconds.
- * Parameters to send to the callback should be specified as arguments after
- * the aCallback argument.
- *
- * @param aCallback Callback to eventually call
- */
- _delayCallback: function MP_delayCallback(aCallback, ...aArgs) {
- if (!this.useAsyncCallbacks) {
- aCallback(...aArgs);
- return;
- }
-
- let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- // Need to keep a reference to the timer, so it doesn't get GC'ed
- this.callbackTimers.push(timer);
- // Capture a stack trace where the timer was set
- // needs the 'new Error' hack until bug 1007656
- this.timerLocations.set(timer, Log.stackTrace(new Error("dummy")));
- timer.initWithCallback(() => {
- let idx = this.callbackTimers.indexOf(timer);
- if (idx == -1) {
- dump("MockProvider._delayCallback lost track of timer set at "
- + (this.timerLocations.get(timer) || "unknown location") + "\n");
- } else {
- this.callbackTimers.splice(idx, 1);
- }
- this.timerLocations.delete(timer);
- aCallback(...aArgs);
- }, this.apiDelay, timer.TYPE_ONE_SHOT);
- }
};
/** *** Mock Addon object for the Mock Provider *****/
function MockAddon(aId, aName, aType, aOperationsRequiringRestart) {
// Only set required attributes.
this.id = aId || "";
this.name = aName || "";
--- a/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
@@ -428,16 +428,17 @@ add_task(async function() {
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
addon.uninstall();
+ await new Promise(executeSoon);
addon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonInstalled(ID);
BootstrapMonitor.checkAddonStarted(ID);
// existing add-on is back
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
@@ -678,16 +679,17 @@ add_task(async function() {
Assert.ok(tempAddon.isActive);
Assert.equal(tempAddon.type, "extension");
Assert.equal(tempAddon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
tempAddon.uninstall();
unpacked_addon.remove(true);
addon.userDisabled = false;
+ await new Promise(executeSoon);
addon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonStarted(ID);
// existing add-on is back
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_events.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_events.js
@@ -11,16 +11,17 @@ add_task(async function() {
async function expectEvents(expected, fn) {
let events = Object.keys(expected);
for (let event of events) {
triggered[event] = false;
}
await fn();
+ await new Promise(executeSoon);
for (let event of events) {
equal(triggered[event], expected[event],
`Event ${event} was${expected[event] ? "" : " not"} triggered`);
}
}
await promiseStartupManager();