--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -1888,19 +1888,17 @@ var LocalAddonInstall = class extends Ad
XPIProvider.removeActiveInstall(this);
AddonManagerPrivate.callInstallListeners("onNewInstall",
this.listeners,
this.wrapper);
flushJarCache(this.file);
return;
}
- let addon = await new Promise(resolve => {
- XPIDatabase.getVisibleAddonForID(this.addon.id, resolve);
- });
+ let addon = await XPIDatabase.getVisibleAddonForID(this.addon.id);
this.existingAddon = addon;
this.addon.updateBlocklistState({oldAddon: this.existingAddon});
this.addon.updateDate = Date.now();
this.addon.installDate = addon ? addon.installDate : this.addon.updateDate;
if (!this.addon.isCompatible) {
this.state = AddonManager.STATE_CHECKING;
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -66,68 +66,42 @@ const PROP_JSON_FIELDS = ["id", "syncGUI
"blocklistState", "blocklistURL", "startupData"];
// Time to wait before async save of XPI JSON database, in milliseconds
const ASYNC_SAVE_DELAY_MS = 20;
/**
* Asynchronously fill in the _repositoryAddon field for one addon
*/
-function getRepositoryAddon(aAddon, aCallback) {
- if (!aAddon) {
- aCallback(aAddon);
- return;
+async function getRepositoryAddon(aAddon, aCallback) {
+ let addon;
+ if (aAddon) {
+ addon = await AddonRepository.getCachedAddonByID(aAddon.id);
+ aAddon._repositoryAddon = addon;
}
- AddonRepository.getCachedAddonByID(aAddon.id, repoAddon => {
- aAddon._repositoryAddon = repoAddon;
- aCallback(aAddon);
- });
+ if (aCallback) {
+ aCallback(addon);
+ }
+ return addon;
}
/**
* Wrap an API-supplied function in an exception handler to make it safe to call
*/
function makeSafe(aCallback) {
return function(...aArgs) {
try {
aCallback(...aArgs);
} catch (ex) {
logger.warn("XPI Database callback failed", ex);
}
};
}
/**
- * A helper method to asynchronously call a function on an array of objects.
- * Returns a promise that resolves with the results for each function call in
- * the same order as the aObjects array.
- * WARNING: not currently error-safe; if the async function does not call its
- * callback for any of the array elements, asyncMap will never resolve.
- *
- * @param aObjects
- * The array of objects to process asynchronously
- * @param aMethod
- * Function with signature function(object, function(f_of_object))
- */
-function asyncMap(aObjects, aMethod) {
- let methodCalls = aObjects.map(obj => {
- return new Promise(resolve => {
- try {
- aMethod(obj, resolve);
- } catch (e) {
- logger.error("Async map function failed", e);
- resolve(undefined);
- }
- });
- });
-
- return Promise.all(methodCalls);
-}
-
-/**
* Copies properties from one object to another. If no target object is passed
* a new object will be created and returned.
*
* @param aObject
* An object to copy from
* @param aProperties
* An array of properties to be copied
* @param aTarget
@@ -658,17 +632,17 @@ this.XPIDatabase = {
* aFilter or an empty array if none match.
* @return a Promise that resolves to the list of add-ons matching aFilter or
* an empty array if none match
*/
async getAddonList(aFilter, aCallback) {
try {
let addonDB = await this.asyncLoadDB();
let addonList = _filterDB(addonDB, aFilter);
- let addons = await asyncMap(addonList, getRepositoryAddon);
+ let addons = await Promise.all(addonList.map(addon => getRepositoryAddon(addon)));
if (aCallback) {
makeSafe(aCallback)(addons);
}
return addons;
} catch (error) {
logger.error("getAddonList failed", error);
if (aCallback) {
makeSafe(aCallback)([]);
@@ -683,17 +657,17 @@ this.XPIDatabase = {
* Function that takes an addon instance and returns
* true if that addon should be selected
* @param aCallback
* Called back with the addon, or null if no matching addon is found
*/
getAddon(aFilter, aCallback) {
return this.asyncLoadDB().then(
addonDB => {
- getRepositoryAddon(_findAddon(addonDB, aFilter), makeSafe(aCallback));
+ return getRepositoryAddon(_findAddon(addonDB, aFilter));
})
.catch(
error => {
logger.error("getAddon failed", error);
makeSafe(aCallback)(null);
});
},
@@ -704,59 +678,59 @@ this.XPIDatabase = {
* @param aId
* The ID of the add-on to retrieve
* @param aLocation
* The name of the install location
* @param aCallback
* A callback to pass the DBAddonInternal to
*/
getAddonInLocation(aId, aLocation, aCallback) {
- this.asyncLoadDB().then(
+ return this.asyncLoadDB().then(
addonDB => getRepositoryAddon(addonDB.get(aLocation + ":" + aId),
makeSafe(aCallback)));
},
/**
* Asynchronously get all the add-ons in a particular install location.
*
* @param aLocation
* The name of the install location
* @param aCallback
* A callback to pass the array of DBAddonInternals to
*/
getAddonsInLocation(aLocation, aCallback) {
- this.getAddonList(aAddon => aAddon._installLocation.name == aLocation, aCallback);
+ return this.getAddonList(aAddon => aAddon._installLocation.name == aLocation, aCallback);
},
/**
* Asynchronously gets the add-on with the specified ID that is visible.
*
* @param aId
* The ID of the add-on to retrieve
* @param aCallback
* A callback to pass the DBAddonInternal to
*/
getVisibleAddonForID(aId, aCallback) {
- this.getAddon(aAddon => ((aAddon.id == aId) && aAddon.visible),
- aCallback);
+ return this.getAddon(aAddon => ((aAddon.id == aId) && aAddon.visible),
+ aCallback);
},
/**
* Asynchronously gets the visible add-ons, optionally restricting by type.
*
* @param aTypes
* An array of types to include or null to include all types
* @param aCallback
* A callback to pass the array of DBAddonInternals to
*/
getVisibleAddons(aTypes, aCallback) {
- this.getAddonList(aAddon => (aAddon.visible &&
- (!aTypes || (aTypes.length == 0) ||
- (aTypes.indexOf(aAddon.type) > -1))),
- aCallback);
+ return this.getAddonList(aAddon => (aAddon.visible &&
+ (!aTypes || (aTypes.length == 0) ||
+ (aTypes.indexOf(aAddon.type) > -1))),
+ aCallback);
},
/**
* Synchronously gets all add-ons of a particular type(s).
*
* @param aType, aType2, ...
* The type(s) of add-on to retrieve
* @return an array of DBAddonInternals
@@ -802,17 +776,17 @@ this.XPIDatabase = {
* Asynchronously gets all add-ons with pending operations.
*
* @param aTypes
* The types of add-ons to retrieve or null to get all types
* @param aCallback
* A callback to pass the array of DBAddonInternal to
*/
getVisibleAddonsWithPendingOperations(aTypes, aCallback) {
- this.getAddonList(
+ return this.getAddonList(
aAddon => (aAddon.visible &&
aAddon.pendingUninstall &&
(!aTypes || (aTypes.length == 0) || (aTypes.indexOf(aAddon.type) > -1))),
aCallback);
},
/**
* Asynchronously get an add-on by its Sync GUID.
@@ -820,18 +794,18 @@ this.XPIDatabase = {
* @param aGUID
* Sync GUID of add-on to fetch
* @param aCallback
* A callback to pass the DBAddonInternal record to. Receives null
* if no add-on with that GUID is found.
*
*/
getAddonBySyncGUID(aGUID, aCallback) {
- this.getAddon(aAddon => aAddon.syncGUID == aGUID,
- aCallback);
+ return this.getAddon(aAddon => aAddon.syncGUID == aGUID,
+ aCallback);
},
/**
* Synchronously gets all add-ons in the database.
* This is only called from the preference observer for the default
* compatibility version preference, so we can return an empty list if
* we haven't loaded the database yet.
*