mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1462516: Move more XPI database code out of XPIProvider.jsm. r=aswan
MozReview-Commit-ID: IIoP5GPa4Cu --HG-- extra : rebase_source : 4993834aa10f1a763ce12c72db44aa0af0f1395e
This commit is contained in:
parent
f6471189bd
commit
10b1f3e064
@ -738,16 +738,7 @@ class AddonValidator extends CollectionValidator {
|
||||
}
|
||||
|
||||
async getClientItems() {
|
||||
const installed = await AddonManager.getAllAddons();
|
||||
const addonsWithPendingOperation = await AddonManager.getAddonsWithOperationsByTypes(["extension", "theme"]);
|
||||
// Addons pending install won't be in the first list, but addons pending
|
||||
// uninstall/enable/disable will be in both lists.
|
||||
let all = new Map(installed.map(addon => [addon.id, addon]));
|
||||
for (let addon of addonsWithPendingOperation) {
|
||||
all.set(addon.id, addon);
|
||||
}
|
||||
// Convert to an array since Map.prototype.values returns an iterable
|
||||
return [...all.values()];
|
||||
return AddonManager.getAllAddons();
|
||||
}
|
||||
|
||||
normalizeClientItem(item) {
|
||||
|
@ -2331,37 +2331,6 @@ var AddonManagerInternal = {
|
||||
return this.getAddonsByTypes(null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronously gets add-ons that have operations waiting for an application
|
||||
* restart to complete.
|
||||
*
|
||||
* @param aTypes
|
||||
* An optional array of types to retrieve. Each type is a string name
|
||||
*/
|
||||
getAddonsWithOperationsByTypes(aTypes) {
|
||||
if (!gStarted)
|
||||
throw Components.Exception("AddonManager is not initialized",
|
||||
Cr.NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (aTypes && !Array.isArray(aTypes))
|
||||
throw Components.Exception("aTypes must be an array or null",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
return (async () => {
|
||||
let addons = [];
|
||||
|
||||
for (let provider of this.providers) {
|
||||
let providerAddons = await promiseCallProvider(
|
||||
provider, "getAddonsWithOperationsByTypes", aTypes);
|
||||
|
||||
if (providerAddons)
|
||||
addons.push(...providerAddons);
|
||||
}
|
||||
|
||||
return addons;
|
||||
})();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new AddonManagerListener if the listener is not already registered.
|
||||
*
|
||||
@ -3389,10 +3358,6 @@ var AddonManager = {
|
||||
return AddonManagerInternal.getAddonsByIDs(aIDs);
|
||||
},
|
||||
|
||||
getAddonsWithOperationsByTypes(aTypes) {
|
||||
return AddonManagerInternal.getAddonsWithOperationsByTypes(aTypes);
|
||||
},
|
||||
|
||||
getAddonsByTypes(aTypes) {
|
||||
return AddonManagerInternal.getAddonsByTypes(aTypes);
|
||||
},
|
||||
|
@ -122,16 +122,6 @@ var PluginProvider = {
|
||||
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
|
||||
*/
|
||||
async getAddonsWithOperationsByTypes(aTypes) {
|
||||
return [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get the current AddonInstalls, optionally restricting by type.
|
||||
*
|
||||
|
@ -28,6 +28,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
ExtensionUtils: "resource://gre/modules/ExtensionUtils.jsm",
|
||||
FileUtils: "resource://gre/modules/FileUtils.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
PermissionsUtils: "resource://gre/modules/PermissionsUtils.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
|
||||
Blocklist: "resource://gre/modules/Blocklist.jsm",
|
||||
@ -35,6 +36,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
UpdateChecker: "resource://gre/modules/addons/XPIInstall.jsm",
|
||||
XPIInstall: "resource://gre/modules/addons/XPIInstall.jsm",
|
||||
XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm",
|
||||
XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm",
|
||||
verifyBundleSignedState: "resource://gre/modules/addons/XPIInstall.jsm",
|
||||
});
|
||||
|
||||
@ -44,23 +46,15 @@ const {nsIBlocklistService} = Ci;
|
||||
/* globals
|
||||
* BOOTSTRAP_REASONS,
|
||||
* DB_SCHEMA,
|
||||
* SIGNED_TYPES,
|
||||
* XPIProvider,
|
||||
* XPIStates,
|
||||
* isTheme,
|
||||
* isWebExtension,
|
||||
* recordAddonTelemetry,
|
||||
*/
|
||||
|
||||
for (let sym of [
|
||||
"BOOTSTRAP_REASONS",
|
||||
"DB_SCHEMA",
|
||||
"SIGNED_TYPES",
|
||||
"XPIProvider",
|
||||
"XPIStates",
|
||||
"isTheme",
|
||||
"isWebExtension",
|
||||
"recordAddonTelemetry",
|
||||
]) {
|
||||
XPCOMUtils.defineLazyGetter(this, sym, () => XPIInternal[sym]);
|
||||
}
|
||||
@ -88,6 +82,7 @@ const PREF_DB_SCHEMA = "extensions.databaseSchema";
|
||||
const PREF_EM_AUTO_DISABLED_SCOPES = "extensions.autoDisableScopes";
|
||||
const PREF_EM_EXTENSION_FORMAT = "extensions.";
|
||||
const PREF_PENDING_OPERATIONS = "extensions.pendingOperations";
|
||||
const PREF_XPI_PERMISSIONS_BRANCH = "xpinstall.";
|
||||
const PREF_XPI_SIGNATURES_DEV_ROOT = "xpinstall.signatures.dev-root";
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
@ -137,6 +132,22 @@ const LEGACY_TYPES = new Set([
|
||||
"extension",
|
||||
]);
|
||||
|
||||
// Some add-on types that we track internally are presented as other types
|
||||
// externally
|
||||
const TYPE_ALIASES = {
|
||||
"webextension": "extension",
|
||||
"webextension-dictionary": "dictionary",
|
||||
"webextension-langpack": "locale",
|
||||
"webextension-theme": "theme",
|
||||
};
|
||||
|
||||
const SIGNED_TYPES = new Set([
|
||||
"extension",
|
||||
"webextension",
|
||||
"webextension-langpack",
|
||||
"webextension-theme",
|
||||
]);
|
||||
|
||||
// Time to wait before async save of XPI JSON database, in milliseconds
|
||||
const ASYNC_SAVE_DELAY_MS = 20;
|
||||
|
||||
@ -195,6 +206,46 @@ async function getRepositoryAddon(aAddon) {
|
||||
return aAddon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that determines whether an addon of a certain type is a
|
||||
* theme.
|
||||
*
|
||||
* @param {string} type
|
||||
* The add-on type to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isTheme(type) {
|
||||
return type == "theme" || TYPE_ALIASES[type] == "theme";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of API types to a list of API types and any aliases for those
|
||||
* types.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* An array of types or null for all types
|
||||
* @returns {Set<string>?}
|
||||
* An set of types or null for all types
|
||||
*/
|
||||
function getAllAliasesForTypes(aTypes) {
|
||||
if (!aTypes)
|
||||
return null;
|
||||
|
||||
let types = new Set(aTypes);
|
||||
for (let [alias, type] of Object.entries(TYPE_ALIASES)) {
|
||||
// Add any alias for the internal type
|
||||
if (types.has(type)) {
|
||||
types.add(alias);
|
||||
} else {
|
||||
// If this internal type was explicitly requested and its external
|
||||
// type wasn't, ignore it.
|
||||
types.delete(alias);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies properties from one object to another. If no target object is passed
|
||||
* a new object will be created and returned.
|
||||
@ -667,7 +718,7 @@ AddonWrapper = class {
|
||||
}
|
||||
|
||||
get type() {
|
||||
return XPIInternal.getExternalType(addonFor(this).type);
|
||||
return XPIDatabase.getExternalType(addonFor(this).type);
|
||||
}
|
||||
|
||||
get isWebExtension() {
|
||||
@ -1676,6 +1727,15 @@ this.XPIDatabase = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Imports the xpinstall permissions from preferences into the permissions
|
||||
* manager for the user to change later.
|
||||
*/
|
||||
importPermissions() {
|
||||
PermissionsUtils.importFromPrefs(PREF_XPI_PERMISSIONS_BRANCH,
|
||||
XPIInternal.XPI_PERMISSION);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when a new add-on has been enabled when only one add-on of that type
|
||||
* can be enabled.
|
||||
@ -1707,6 +1767,23 @@ this.XPIDatabase = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts an internal add-on type to the type presented through the API.
|
||||
*
|
||||
* @param {string} aType
|
||||
* The internal add-on type
|
||||
* @returns {string}
|
||||
* An external add-on type
|
||||
*/
|
||||
getExternalType(aType) {
|
||||
if (aType in TYPE_ALIASES)
|
||||
return TYPE_ALIASES[aType];
|
||||
return aType;
|
||||
},
|
||||
|
||||
isTheme,
|
||||
SIGNED_TYPES,
|
||||
|
||||
/**
|
||||
* Asynchronously list all addons that match the filter function
|
||||
*
|
||||
@ -1795,14 +1872,13 @@ this.XPIDatabase = {
|
||||
/**
|
||||
* Asynchronously gets the visible add-ons, optionally restricting by type.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* @param {Set<string>?} aTypes
|
||||
* An array of types to include or null to include all types
|
||||
* @returns {Promise<Array<AddonInternal>>}
|
||||
*/
|
||||
getVisibleAddons(aTypes) {
|
||||
return this.getAddonList(aAddon => (aAddon.visible &&
|
||||
(!aTypes || (aTypes.length == 0) ||
|
||||
(aTypes.indexOf(aAddon.type) > -1))));
|
||||
(!aTypes || aTypes.has(aAddon.type))));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1830,7 +1906,7 @@ this.XPIDatabase = {
|
||||
/**
|
||||
* Asynchronously gets all add-ons with pending operations.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* @param {Set<string>?} aTypes
|
||||
* The types of add-ons to retrieve or null to get all types
|
||||
* @returns {Promise<Array<AddonInternal>>}
|
||||
*/
|
||||
@ -1838,18 +1914,7 @@ this.XPIDatabase = {
|
||||
return this.getAddonList(
|
||||
aAddon => (aAddon.visible &&
|
||||
aAddon.pendingUninstall &&
|
||||
(!aTypes || (aTypes.length == 0) || (aTypes.indexOf(aAddon.type) > -1))));
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronously get an add-on by its Sync GUID.
|
||||
*
|
||||
* @param {string} aGUID
|
||||
* Sync GUID of add-on to fetch
|
||||
* @returns {Promise<AddonInternal?>}
|
||||
*/
|
||||
getAddonBySyncGUID(aGUID) {
|
||||
return this.getAddon(aAddon => aAddon.syncGUID == aGUID);
|
||||
(!aTypes || aTypes.has(aAddon.type))));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1867,6 +1932,61 @@ this.XPIDatabase = {
|
||||
return _filterDB(this.addonDB, aAddon => true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get an Addon with a particular ID.
|
||||
*
|
||||
* @param {string} aId
|
||||
* The ID of the add-on to retrieve
|
||||
* @returns {Addon?}
|
||||
*/
|
||||
async getAddonByID(aId) {
|
||||
let aAddon = await this.getVisibleAddonForID(aId);
|
||||
return aAddon ? aAddon.wrapper : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously returns the Addon object for the add-on with the
|
||||
* given ID.
|
||||
*
|
||||
* *DO NOT USE THIS IF YOU CAN AT ALL AVOID IT*
|
||||
*
|
||||
* This will always return null if the add-on database has not been
|
||||
* loaded, and the resulting Addon object may not yet include a
|
||||
* reference to its corresponding repository add-on object.
|
||||
*
|
||||
* @param {string} aId
|
||||
* The ID of the add-on to return.
|
||||
* @returns {DBAddonInternal?}
|
||||
* The Addon object, if available.
|
||||
*/
|
||||
syncGetAddonByID(aId) {
|
||||
let aAddon = this.syncGetVisibleAddonForID(aId);
|
||||
return aAddon ? aAddon.wrapper : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Obtain an Addon having the specified Sync GUID.
|
||||
*
|
||||
* @param {string} aGUID
|
||||
* String GUID of add-on to retrieve
|
||||
* @returns {Addon?}
|
||||
*/
|
||||
async getAddonBySyncGUID(aGUID) {
|
||||
let addon = await this.getAddon(aAddon => aAddon.syncGUID == aGUID);
|
||||
return addon ? addon.wrapper : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get Addons of a particular type.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* An array of types to fetch. Can be null to get all types.
|
||||
* @returns {Addon[]}
|
||||
*/
|
||||
async getAddonsByTypes(aTypes) {
|
||||
let addons = await this.getVisibleAddons(getAllAliasesForTypes(aTypes));
|
||||
return addons.map(a => a.wrapper);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if signing is required for the given add-on type.
|
||||
@ -2173,6 +2293,7 @@ this.XPIDatabase = {
|
||||
XPIProvider.runPhase);
|
||||
this.syncLoadDB(true);
|
||||
}
|
||||
|
||||
logger.debug("Updating add-on states");
|
||||
for (let [, addon] of this.addonDB) {
|
||||
let newActive = (addon.visible && !addon.disabled && !addon.pendingUninstall);
|
||||
@ -2181,6 +2302,8 @@ this.XPIDatabase = {
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2300,6 +2423,32 @@ this.XPIDatabase = {
|
||||
return isDisabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the appDisabled property for all add-ons.
|
||||
*/
|
||||
updateAddonAppDisabledStates() {
|
||||
for (let addon of this.getAddons()) {
|
||||
this.updateAddonDisabledState(addon);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the repositoryAddon property for all add-ons.
|
||||
*/
|
||||
async updateAddonRepositoryData() {
|
||||
let addons = await this.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);
|
||||
}
|
||||
})));
|
||||
},
|
||||
|
||||
/**
|
||||
* Record a bit of per-addon telemetry.
|
||||
*
|
||||
|
@ -47,7 +47,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
InstallRDF: "resource://gre/modules/addons/RDFManifestConverter.jsm",
|
||||
XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm",
|
||||
XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm",
|
||||
XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "uuidGen",
|
||||
@ -88,20 +87,18 @@ const PREF_XPI_DIRECT_WHITELISTED = "xpinstall.whitelist.directRequest";
|
||||
const PREF_XPI_FILE_WHITELISTED = "xpinstall.whitelist.fileRequest";
|
||||
const PREF_XPI_WHITELIST_REQUIRED = "xpinstall.whitelist.required";
|
||||
|
||||
/* globals BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, PREF_BRANCH_INSTALLED_ADDON, PREF_SYSTEM_ADDON_SET, TEMPORARY_ADDON_SUFFIX, SIGNED_TYPES, TOOLKIT_ID, XPI_PERMISSION, XPIStates, getExternalType, isTheme, isWebExtension, iterDirectory */
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
/* globals BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, PREF_BRANCH_INSTALLED_ADDON, PREF_SYSTEM_ADDON_SET, TEMPORARY_ADDON_SUFFIX, XPI_PERMISSION, XPIStates, isWebExtension, iterDirectory */
|
||||
const XPI_INTERNAL_SYMBOLS = [
|
||||
"BOOTSTRAP_REASONS",
|
||||
"KEY_APP_SYSTEM_ADDONS",
|
||||
"KEY_APP_SYSTEM_DEFAULTS",
|
||||
"PREF_BRANCH_INSTALLED_ADDON",
|
||||
"PREF_SYSTEM_ADDON_SET",
|
||||
"SIGNED_TYPES",
|
||||
"TEMPORARY_ADDON_SUFFIX",
|
||||
"TOOLKIT_ID",
|
||||
"XPI_PERMISSION",
|
||||
"XPIStates",
|
||||
"getExternalType",
|
||||
"isTheme",
|
||||
"isWebExtension",
|
||||
"iterDirectory",
|
||||
];
|
||||
@ -110,6 +107,10 @@ for (let name of XPI_INTERNAL_SYMBOLS) {
|
||||
XPCOMUtils.defineLazyGetter(this, name, () => XPIInternal[name]);
|
||||
}
|
||||
|
||||
function isTheme(type) {
|
||||
return XPIDatabase.isTheme(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nsIFile instance for the given path, relative to the given
|
||||
* base file, if provided.
|
||||
@ -960,7 +961,7 @@ function shouldVerifySignedState(aAddon) {
|
||||
|
||||
// Otherwise only check signatures if signing is enabled and the add-on is one
|
||||
// of the signed types.
|
||||
return AddonSettings.ADDON_SIGNING && SIGNED_TYPES.has(aAddon.type);
|
||||
return AddonSettings.ADDON_SIGNING && XPIDatabase.SIGNED_TYPES.has(aAddon.type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2447,7 +2448,7 @@ AddonInstallWrapper.prototype = {
|
||||
},
|
||||
|
||||
get type() {
|
||||
return getExternalType(installFor(this).type);
|
||||
return XPIDatabase.getExternalType(installFor(this).type);
|
||||
},
|
||||
|
||||
get iconURL() {
|
||||
@ -2522,7 +2523,7 @@ var UpdateChecker = function(aAddon, aListener, aReason, aAppVersion, aPlatformV
|
||||
|
||||
this.addon = aAddon;
|
||||
aAddon._updateCheck = this;
|
||||
XPIProvider.doing(this);
|
||||
XPIInstall.doing(this);
|
||||
this.listener = aListener;
|
||||
this.appVersion = aAppVersion;
|
||||
this.platformVersion = aPlatformVersion;
|
||||
@ -2583,7 +2584,7 @@ UpdateChecker.prototype = {
|
||||
* The list of update details for the add-on
|
||||
*/
|
||||
async onUpdateCheckComplete(aUpdates) {
|
||||
XPIProvider.done(this.addon._updateCheck);
|
||||
XPIInstall.done(this.addon._updateCheck);
|
||||
this.addon._updateCheck = null;
|
||||
let AUC = AddonUpdateChecker;
|
||||
|
||||
@ -2680,7 +2681,7 @@ UpdateChecker.prototype = {
|
||||
* An error status
|
||||
*/
|
||||
onUpdateCheckError(aError) {
|
||||
XPIProvider.done(this.addon._updateCheck);
|
||||
XPIInstall.done(this.addon._updateCheck);
|
||||
this.addon._updateCheck = null;
|
||||
this.callListener("onNoCompatibilityUpdateAvailable", this.addon.wrapper);
|
||||
this.callListener("onNoUpdateAvailable", this.addon.wrapper);
|
||||
@ -3376,6 +3377,34 @@ var XPIInstall = {
|
||||
recursiveRemove,
|
||||
syncLoadManifestFromFile,
|
||||
|
||||
// Keep track of in-progress operations that support cancel()
|
||||
_inProgress: [],
|
||||
|
||||
doing(aCancellable) {
|
||||
this._inProgress.push(aCancellable);
|
||||
},
|
||||
|
||||
done(aCancellable) {
|
||||
let i = this._inProgress.indexOf(aCancellable);
|
||||
if (i != -1) {
|
||||
this._inProgress.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
cancelAll() {
|
||||
// Cancelling one may alter _inProgress, so don't use a simple iterator
|
||||
while (this._inProgress.length > 0) {
|
||||
let c = this._inProgress.shift();
|
||||
try {
|
||||
c.cancel();
|
||||
} catch (e) {
|
||||
logger.warn("Cancel failed", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* The expected ID of the add-on.
|
||||
@ -3677,7 +3706,7 @@ var XPIInstall = {
|
||||
(uri.schemeIs("chrome") || uri.schemeIs("file")))
|
||||
return true;
|
||||
|
||||
XPIProvider.importPermissions();
|
||||
XPIDatabase.importPermissions();
|
||||
|
||||
let permission = Services.perms.testPermissionFromPrincipal(aInstallingPrincipal, XPI_PERMISSION);
|
||||
if (permission == Ci.nsIPermissionManager.DENY_ACTION)
|
||||
@ -3758,7 +3787,7 @@ var XPIInstall = {
|
||||
let results = [...this.installs];
|
||||
if (aTypes) {
|
||||
results = results.filter(install => {
|
||||
return aTypes.includes(getExternalType(install.type));
|
||||
return aTypes.includes(XPIDatabase.getExternalType(install.type));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,12 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AddonRepository: "resource://gre/modules/addons/AddonRepository.jsm",
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
|
||||
Dictionary: "resource://gre/modules/Extension.jsm",
|
||||
Extension: "resource://gre/modules/Extension.jsm",
|
||||
Langpack: "resource://gre/modules/Extension.jsm",
|
||||
FileUtils: "resource://gre/modules/FileUtils.jsm",
|
||||
PermissionsUtils: "resource://gre/modules/PermissionsUtils.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
ConsoleAPI: "resource://gre/modules/Console.jsm",
|
||||
JSONFile: "resource://gre/modules/JSONFile.jsm",
|
||||
@ -62,7 +60,6 @@ const PREF_EM_STARTUP_SCAN_SCOPES = "extensions.startupScanScopes";
|
||||
// xpinstall.signatures.required only supported in dev builds
|
||||
const PREF_XPI_SIGNATURES_REQUIRED = "xpinstall.signatures.required";
|
||||
const PREF_LANGPACK_SIGNATURES = "extensions.langpacks.signatures.required";
|
||||
const PREF_XPI_PERMISSIONS_BRANCH = "xpinstall.";
|
||||
const PREF_INSTALL_DISTRO_ADDONS = "extensions.installDistroAddons";
|
||||
const PREF_BRANCH_INSTALLED_ADDON = "extensions.installedDistroAddon.";
|
||||
const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet";
|
||||
@ -81,7 +78,6 @@ const DIR_STAGE = "staged";
|
||||
const DIR_TRASH = "trash";
|
||||
|
||||
const FILE_XPI_STATES = "addonStartup.json.lz4";
|
||||
const FILE_DATABASE = "extensions.json";
|
||||
|
||||
const KEY_PROFILEDIR = "ProfD";
|
||||
const KEY_ADDON_APP_DIR = "XREAddonAppDir";
|
||||
@ -107,11 +103,9 @@ const STARTUP_MTIME_SCOPES = [KEY_APP_GLOBAL,
|
||||
const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions";
|
||||
const XPI_PERMISSION = "install";
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
const XPI_SIGNATURE_CHECK_PERIOD = 24 * 60 * 60;
|
||||
|
||||
XPCOMUtils.defineConstant(this, "DB_SCHEMA", 26);
|
||||
const DB_SCHEMA = 26;
|
||||
|
||||
const NOTIFICATION_TOOLBOX_CONNECTION_CHANGE = "toolbox-connection-change";
|
||||
|
||||
@ -138,22 +132,6 @@ const BOOTSTRAP_REASONS = {
|
||||
ADDON_DOWNGRADE: 8
|
||||
};
|
||||
|
||||
// Some add-on types that we track internally are presented as other types
|
||||
// externally
|
||||
const TYPE_ALIASES = {
|
||||
"webextension": "extension",
|
||||
"webextension-dictionary": "dictionary",
|
||||
"webextension-langpack": "locale",
|
||||
"webextension-theme": "theme",
|
||||
};
|
||||
|
||||
const SIGNED_TYPES = new Set([
|
||||
"extension",
|
||||
"webextension",
|
||||
"webextension-langpack",
|
||||
"webextension-theme",
|
||||
]);
|
||||
|
||||
const ALL_EXTERNAL_TYPES = new Set([
|
||||
"dictionary",
|
||||
"extension",
|
||||
@ -265,18 +243,6 @@ function isWebExtension(type) {
|
||||
return type == "webextension" || type == "webextension-theme";
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that determines whether an addon of a certain type is a
|
||||
* theme.
|
||||
*
|
||||
* @param {string} type
|
||||
* The add-on type to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isTheme(type) {
|
||||
return type == "theme" || TYPE_ALIASES[type] == "theme";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given file, based on its name, should be treated
|
||||
* as an XPI. If the file does not have an appropriate extension, it is
|
||||
@ -326,62 +292,20 @@ function getExpectedID(file) {
|
||||
* True if the add-on should run in safe mode
|
||||
*/
|
||||
function canRunInSafeMode(aAddon) {
|
||||
let location = aAddon.location || null;
|
||||
if (!location) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Even though the updated system add-ons aren't generally run in safe mode we
|
||||
// include them here so their uninstall functions get called when switching
|
||||
// back to the default set.
|
||||
|
||||
// TODO product should make the call about temporary add-ons running
|
||||
// in safe mode. assuming for now that they are.
|
||||
let location = aAddon.location || null;
|
||||
if (!location) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return location.isTemporary || location.isSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an internal add-on type to the type presented through the API.
|
||||
*
|
||||
* @param {string} aType
|
||||
* The internal add-on type
|
||||
* @returns {string}
|
||||
* An external add-on type
|
||||
*/
|
||||
function getExternalType(aType) {
|
||||
if (aType in TYPE_ALIASES)
|
||||
return TYPE_ALIASES[aType];
|
||||
return aType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of API types to a list of API types and any aliases for those
|
||||
* types.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* An array of types or null for all types
|
||||
* @returns {Array<string>?}
|
||||
* An array of types or null for all types
|
||||
*/
|
||||
function getAllAliasesForTypes(aTypes) {
|
||||
if (!aTypes)
|
||||
return null;
|
||||
|
||||
// Build a set of all requested types and their aliases
|
||||
let typeset = new Set(aTypes);
|
||||
|
||||
for (let alias of Object.keys(TYPE_ALIASES)) {
|
||||
// Ignore any requested internal types
|
||||
typeset.delete(alias);
|
||||
|
||||
// Add any alias for the internal type
|
||||
if (typeset.has(TYPE_ALIASES[alias]))
|
||||
typeset.add(alias);
|
||||
}
|
||||
|
||||
return [...typeset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an nsIURI for a file within another file, either a directory or an XPI
|
||||
* file. If aFile is a directory then this will return a file: URI, if it is an
|
||||
@ -2026,34 +1950,6 @@ var XPIProvider = {
|
||||
this._telemetryDetails[aId][aName] = aValue;
|
||||
},
|
||||
|
||||
// Keep track of in-progress operations that support cancel()
|
||||
_inProgress: [],
|
||||
|
||||
doing(aCancellable) {
|
||||
this._inProgress.push(aCancellable);
|
||||
},
|
||||
|
||||
done(aCancellable) {
|
||||
let i = this._inProgress.indexOf(aCancellable);
|
||||
if (i != -1) {
|
||||
this._inProgress.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
cancelAll() {
|
||||
// Cancelling one may alter _inProgress, so don't use a simple iterator
|
||||
while (this._inProgress.length > 0) {
|
||||
let c = this._inProgress.shift();
|
||||
try {
|
||||
c.cancel();
|
||||
} catch (e) {
|
||||
logger.warn("Cancel failed", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setupInstallLocations(aAppChanged) {
|
||||
function DirectoryLoc(aName, aScope, aKey, aPaths, aLocked) {
|
||||
try {
|
||||
@ -2321,12 +2217,12 @@ var XPIProvider = {
|
||||
async shutdown() {
|
||||
logger.debug("shutdown");
|
||||
|
||||
// Stop anything we were doing asynchronously
|
||||
this.cancelAll();
|
||||
|
||||
this.activeAddons.clear();
|
||||
this.allAppGlobal = true;
|
||||
|
||||
// Stop anything we were doing asynchronously
|
||||
XPIInstall.cancelAll();
|
||||
|
||||
for (let install of XPIInstall.installs) {
|
||||
if (install.onShutdown()) {
|
||||
install.onShutdown();
|
||||
@ -2389,13 +2285,7 @@ var XPIProvider = {
|
||||
*/
|
||||
addAddonsToCrashReporter() {
|
||||
if (!(Services.appinfo instanceof Ci.nsICrashReporter) ||
|
||||
!AppConstants.MOZ_CRASHREPORTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// In safe mode no add-ons are loaded so we should not include them in the
|
||||
// crash report
|
||||
if (Services.appinfo.inSafeMode) {
|
||||
Services.appinfo.inSafeMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2532,15 +2422,6 @@ var XPIProvider = {
|
||||
return addons;
|
||||
},
|
||||
|
||||
/**
|
||||
* Imports the xpinstall permissions from preferences into the permissions
|
||||
* manager for the user to change later.
|
||||
*/
|
||||
importPermissions() {
|
||||
PermissionsUtils.importFromPrefs(PREF_XPI_PERMISSIONS_BRANCH,
|
||||
XPI_PERMISSION);
|
||||
},
|
||||
|
||||
getDependentAddons(aAddon) {
|
||||
return Array.from(XPIDatabase.getAddons())
|
||||
.filter(addon => addon.dependencies.includes(aAddon.id));
|
||||
@ -2605,13 +2486,11 @@ var XPIProvider = {
|
||||
}
|
||||
}
|
||||
|
||||
let haveAnyAddons = (XPIStates.size > 0);
|
||||
|
||||
// If the schema appears to have changed then we should update the database
|
||||
if (DB_SCHEMA != Services.prefs.getIntPref(PREF_DB_SCHEMA, 0)) {
|
||||
// If we don't have any add-ons, just update the pref, since we don't need to
|
||||
// write the database
|
||||
if (!haveAnyAddons) {
|
||||
if (!XPIStates.size) {
|
||||
logger.debug("Empty XPI database, setting schema version preference to " + DB_SCHEMA);
|
||||
Services.prefs.setIntPref(PREF_DB_SCHEMA, DB_SCHEMA);
|
||||
} else {
|
||||
@ -2619,14 +2498,6 @@ var XPIProvider = {
|
||||
}
|
||||
}
|
||||
|
||||
// If the database doesn't exist and there are add-ons installed then we
|
||||
// must update the database however if there are no add-ons then there is
|
||||
// no need to update the database.
|
||||
let dbFile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
|
||||
if (!dbFile.exists() && haveAnyAddons) {
|
||||
updateReasons.push("needNewDatabase");
|
||||
}
|
||||
|
||||
// Catch and log any errors during the main startup
|
||||
try {
|
||||
let extensionListChanged = false;
|
||||
@ -2649,7 +2520,7 @@ var XPIProvider = {
|
||||
// If the application crashed before completing any pending operations then
|
||||
// we should perform them now.
|
||||
if (extensionListChanged || hasPendingChanges) {
|
||||
this._updateActiveAddons();
|
||||
XPIDatabase.updateActiveAddons();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2661,12 +2532,6 @@ var XPIProvider = {
|
||||
return false;
|
||||
},
|
||||
|
||||
_updateActiveAddons() {
|
||||
logger.debug("Updating database with changes to installed add-ons");
|
||||
XPIDatabase.updateActiveAddons();
|
||||
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets an array of add-ons which were placed in a known install location
|
||||
* prior to startup of the current session, were detected by a directory scan
|
||||
@ -2679,7 +2544,7 @@ var XPIProvider = {
|
||||
// We detected changes. Update the database to account for them.
|
||||
await XPIDatabase.asyncLoadDB(false);
|
||||
XPIDatabaseReconcile.processFileChanges({}, false);
|
||||
this._updateActiveAddons();
|
||||
XPIDatabase.updateActiveAddons();
|
||||
}
|
||||
|
||||
let addons = await Promise.all(
|
||||
@ -2738,7 +2603,7 @@ var XPIProvider = {
|
||||
getAddonByInstanceID(aInstanceID) {
|
||||
let id = this.getAddonIDByInstanceID(aInstanceID);
|
||||
if (id) {
|
||||
return this.syncGetAddonByID(id);
|
||||
return XPIDatabase.syncGetAddonByID(id);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -2758,53 +2623,11 @@ var XPIProvider = {
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get an Addon with a particular ID.
|
||||
*
|
||||
* @param {string} aId
|
||||
* The ID of the add-on to retrieve
|
||||
* @returns {Addon?}
|
||||
*/
|
||||
async getAddonByID(aId) {
|
||||
let aAddon = await XPIDatabase.getVisibleAddonForID(aId);
|
||||
return aAddon ? aAddon.wrapper : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously returns the Addon object for the add-on with the
|
||||
* given ID.
|
||||
*
|
||||
* *DO NOT USE THIS IF YOU CAN AT ALL AVOID IT*
|
||||
*
|
||||
* This will always return null if the add-on database has not been
|
||||
* loaded, and the resulting Addon object may not yet include a
|
||||
* reference to its corresponding repository add-on object.
|
||||
*
|
||||
* @param {string} aId
|
||||
* The ID of the add-on to return.
|
||||
* @returns {DBAddonInternal?}
|
||||
* The Addon object, if available.
|
||||
*/
|
||||
syncGetAddonByID(aId) {
|
||||
let aAddon = XPIDatabase.syncGetVisibleAddonForID(aId);
|
||||
return aAddon ? aAddon.wrapper : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get Addons of a particular type.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* An array of types to fetch. Can be null to get all types.
|
||||
* @returns {Addon[]}
|
||||
*/
|
||||
async getAddonsByTypes(aTypes) {
|
||||
let typesToGet = getAllAliasesForTypes(aTypes);
|
||||
if (typesToGet && !typesToGet.some(type => ALL_EXTERNAL_TYPES.has(type))) {
|
||||
if (aTypes && !aTypes.some(type => ALL_EXTERNAL_TYPES.has(type))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let addons = await XPIDatabase.getVisibleAddons(typesToGet);
|
||||
return addons.map(a => a.wrapper);
|
||||
return XPIDatabase.getAddonsByTypes(aTypes);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2817,7 +2640,7 @@ var XPIProvider = {
|
||||
async getActiveAddons(aTypes) {
|
||||
// If we already have the database loaded, returning full info is fast.
|
||||
if (this.isDBLoaded) {
|
||||
let addons = await this.getAddonsByTypes(aTypes);
|
||||
let addons = await XPIProvider.getAddonsByTypes(aTypes);
|
||||
return {
|
||||
addons: addons.filter(addon => addon.isActive),
|
||||
fullData: true,
|
||||
@ -2854,70 +2677,6 @@ var XPIProvider = {
|
||||
return {addons: result, fullData: false};
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Obtain an Addon having the specified Sync GUID.
|
||||
*
|
||||
* @param {string} aGUID
|
||||
* String GUID of add-on to retrieve
|
||||
* @returns {Addon?}
|
||||
*/
|
||||
async getAddonBySyncGUID(aGUID) {
|
||||
let addon = await XPIDatabase.getAddonBySyncGUID(aGUID);
|
||||
return addon ? addon.wrapper : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get Addons that have pending operations.
|
||||
*
|
||||
* @param {Array<string>?} aTypes
|
||||
* An array of types to fetch. Can be null to get all types
|
||||
* @returns {Addon[]}
|
||||
*/
|
||||
async getAddonsWithOperationsByTypes(aTypes) {
|
||||
let typesToGet = getAllAliasesForTypes(aTypes);
|
||||
|
||||
let aAddons = await XPIDatabase.getVisibleAddonsWithPendingOperations(typesToGet);
|
||||
let results = aAddons.map(a => a.wrapper);
|
||||
for (let install of XPIInstall.installs) {
|
||||
if (install.state == AddonManager.STATE_INSTALLED &&
|
||||
!(install.addon.inDatabase))
|
||||
results.push(install.addon.wrapper);
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
addonChanged(id, type) {
|
||||
XPIDatabase.addonChanged(id, type);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the appDisabled property for all add-ons.
|
||||
*/
|
||||
updateAddonAppDisabledStates() {
|
||||
let addons = XPIDatabase.getAddons();
|
||||
for (let addon of addons) {
|
||||
XPIDatabase.updateAddonDisabledState(addon);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the repositoryAddon property for all add-ons.
|
||||
*/
|
||||
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;
|
||||
XPIDatabase.updateAddonDisabledState(addon);
|
||||
}
|
||||
})));
|
||||
},
|
||||
|
||||
onDebugConnectionChange({what, connection}) {
|
||||
if (what != "opened")
|
||||
return;
|
||||
@ -2934,22 +2693,23 @@ var XPIProvider = {
|
||||
* @see nsIObserver
|
||||
*/
|
||||
observe(aSubject, aTopic, aData) {
|
||||
if (aTopic == NOTIFICATION_FLUSH_PERMISSIONS) {
|
||||
switch (aTopic) {
|
||||
case NOTIFICATION_FLUSH_PERMISSIONS:
|
||||
if (!aData || aData == XPI_PERMISSION) {
|
||||
this.importPermissions();
|
||||
XPIDatabase.importPermissions();
|
||||
}
|
||||
return;
|
||||
} else if (aTopic == NOTIFICATION_TOOLBOX_CONNECTION_CHANGE) {
|
||||
this.onDebugConnectionChange(aSubject.wrappedJSObject);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
if (aTopic == "nsPref:changed") {
|
||||
case NOTIFICATION_TOOLBOX_CONNECTION_CHANGE:
|
||||
this.onDebugConnectionChange(aSubject.wrappedJSObject);
|
||||
break;
|
||||
|
||||
case "nsPref:changed":
|
||||
switch (aData) {
|
||||
case PREF_XPI_SIGNATURES_REQUIRED:
|
||||
case PREF_LANGPACK_SIGNATURES:
|
||||
case PREF_ALLOW_LEGACY:
|
||||
this.updateAddonAppDisabledStates();
|
||||
XPIDatabase.updateAddonAppDisabledStates();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2964,6 +2724,13 @@ for (let meth of ["getInstallForFile", "getInstallForURL", "getInstallsByTypes",
|
||||
};
|
||||
}
|
||||
|
||||
for (let meth of ["addonChanged", "getAddonByID", "getAddonBySyncGUID",
|
||||
"updateAddonRepositoryData", "updateAddonAppDisabledStates"]) {
|
||||
XPIProvider[meth] = function() {
|
||||
return XPIDatabase[meth](...arguments);
|
||||
};
|
||||
}
|
||||
|
||||
var XPIInternal = {
|
||||
BOOTSTRAP_REASONS,
|
||||
BootstrapScope,
|
||||
@ -2972,19 +2739,14 @@ var XPIInternal = {
|
||||
KEY_APP_SYSTEM_DEFAULTS,
|
||||
PREF_BRANCH_INSTALLED_ADDON,
|
||||
PREF_SYSTEM_ADDON_SET,
|
||||
SIGNED_TYPES,
|
||||
SystemAddonLocation,
|
||||
TEMPORARY_ADDON_SUFFIX,
|
||||
TOOLKIT_ID,
|
||||
TemporaryInstallLocation,
|
||||
XPIProvider,
|
||||
XPIStates,
|
||||
XPI_PERMISSION,
|
||||
awaitPromise,
|
||||
canRunInSafeMode,
|
||||
getExternalType,
|
||||
getURIForResourceInFile,
|
||||
isTheme,
|
||||
isWebExtension,
|
||||
isXPI,
|
||||
iterDirectory,
|
||||
|
@ -908,21 +908,6 @@ MockProvider.prototype = {
|
||||
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
|
||||
*/
|
||||
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;
|
||||
});
|
||||
return addons;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to get the current AddonInstalls, optionally restricting by type.
|
||||
*
|
||||
|
@ -157,7 +157,6 @@ var { AddonManager, AddonManagerInternal, AddonManagerPrivate } = AMscope;
|
||||
|
||||
const promiseAddonByID = AddonManager.getAddonByID;
|
||||
const promiseAddonsByIDs = AddonManager.getAddonsByIDs;
|
||||
const promiseAddonsWithOperationsByTypes = AddonManager.getAddonsWithOperationsByTypes;
|
||||
|
||||
var gPort = null;
|
||||
var gUrlToFileMap = {};
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
// Test the cancellable doing/done/cancelAll API in XPIProvider
|
||||
|
||||
var scope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {});
|
||||
var XPIProvider = scope.XPIProvider;
|
||||
ChromeUtils.import("resource://gre/modules/addons/XPIInstall.jsm");
|
||||
|
||||
function run_test() {
|
||||
// Check that cancelling with nothing in progress doesn't blow up
|
||||
XPIProvider.cancelAll();
|
||||
XPIInstall.cancelAll();
|
||||
|
||||
// Check that a basic object gets cancelled
|
||||
let getsCancelled = {
|
||||
@ -20,17 +19,17 @@ function run_test() {
|
||||
this.isCancelled = true;
|
||||
}
|
||||
};
|
||||
XPIProvider.doing(getsCancelled);
|
||||
XPIProvider.cancelAll();
|
||||
XPIInstall.doing(getsCancelled);
|
||||
XPIInstall.cancelAll();
|
||||
Assert.ok(getsCancelled.isCancelled);
|
||||
|
||||
// Check that if we complete a cancellable, it doesn't get cancelled
|
||||
let doesntGetCancelled = {
|
||||
cancel: () => do_throw("This should not have been cancelled")
|
||||
};
|
||||
XPIProvider.doing(doesntGetCancelled);
|
||||
Assert.ok(XPIProvider.done(doesntGetCancelled));
|
||||
XPIProvider.cancelAll();
|
||||
XPIInstall.doing(doesntGetCancelled);
|
||||
Assert.ok(XPIInstall.done(doesntGetCancelled));
|
||||
XPIInstall.cancelAll();
|
||||
|
||||
// A cancellable that adds a cancellable
|
||||
getsCancelled.isCancelled = false;
|
||||
@ -40,11 +39,11 @@ function run_test() {
|
||||
if (this.isCancelled)
|
||||
do_throw("Already cancelled");
|
||||
this.isCancelled = true;
|
||||
XPIProvider.doing(getsCancelled);
|
||||
XPIInstall.doing(getsCancelled);
|
||||
}
|
||||
};
|
||||
XPIProvider.doing(addsAnother);
|
||||
XPIProvider.cancelAll();
|
||||
XPIInstall.doing(addsAnother);
|
||||
XPIInstall.cancelAll();
|
||||
Assert.ok(addsAnother.isCancelled);
|
||||
Assert.ok(getsCancelled.isCancelled);
|
||||
|
||||
@ -56,11 +55,11 @@ function run_test() {
|
||||
if (this.isCancelled)
|
||||
do_throw("Already cancelled");
|
||||
this.isCancelled = true;
|
||||
XPIProvider.done(doesntGetCancelled);
|
||||
XPIInstall.done(doesntGetCancelled);
|
||||
}
|
||||
};
|
||||
XPIProvider.doing(removesAnother);
|
||||
XPIProvider.doing(doesntGetCancelled);
|
||||
XPIProvider.cancelAll();
|
||||
XPIInstall.doing(removesAnother);
|
||||
XPIInstall.doing(doesntGetCancelled);
|
||||
XPIInstall.cancelAll();
|
||||
Assert.ok(removesAnother.isCancelled);
|
||||
}
|
||||
|
@ -274,9 +274,6 @@ add_task(async function test_1() {
|
||||
|
||||
let dir = do_get_addon_root_uri(profileDir, ID1);
|
||||
equal(b1.getResourceURI("bootstrap.js").spec, dir + "bootstrap.js");
|
||||
|
||||
let list = await AddonManager.getAddonsWithOperationsByTypes(null);
|
||||
equal(list.length, 0);
|
||||
});
|
||||
|
||||
// Tests that disabling doesn't require a restart
|
||||
@ -1192,9 +1189,6 @@ add_task(async function test_23() {
|
||||
let dir = do_get_addon_root_uri(profileDir, ID1);
|
||||
equal(b1.getResourceURI("bootstrap.js").spec, dir + "bootstrap.js");
|
||||
|
||||
let list = await AddonManager.getAddonsWithOperationsByTypes(null);
|
||||
equal(list.length, 0);
|
||||
|
||||
await promiseRestartManager();
|
||||
|
||||
let b1_2 = await AddonManager.getAddonByID(ID1);
|
||||
|
@ -183,9 +183,6 @@ add_task(async function test_1() {
|
||||
} catch (e) {
|
||||
// Expected the chrome url to not be registered
|
||||
}
|
||||
|
||||
let list = await AddonManager.getAddonsWithOperationsByTypes(null);
|
||||
equal(list.length, 0);
|
||||
});
|
||||
|
||||
// Tests that disabling doesn't require a restart
|
||||
@ -480,9 +477,6 @@ add_task(async function test_23() {
|
||||
ok(!addon.hasResource("bootstrap.js"));
|
||||
do_check_in_crash_annotation(ID_DICT, "1.0");
|
||||
|
||||
let list = await AddonManager.getAddonsWithOperationsByTypes(null);
|
||||
equal(list.length, 0);
|
||||
|
||||
await promiseRestartManager();
|
||||
|
||||
addon = await AddonManager.getAddonByID(ID_DICT);
|
||||
|
@ -26,9 +26,6 @@ async function run_test_1() {
|
||||
let addons = await AddonManager.getAddonsByTypes(null);
|
||||
Assert.equal(gCount, addons.length);
|
||||
|
||||
let pendingAddons = await AddonManager.getAddonsWithOperationsByTypes(null);
|
||||
Assert.equal(0, pendingAddons.length);
|
||||
|
||||
executeSoon(run_test_2);
|
||||
}
|
||||
|
||||
|
@ -203,9 +203,6 @@ add_task(async function test_1() {
|
||||
addon = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
|
||||
ok(addon);
|
||||
|
||||
let pendingAddons = await AddonManager.getAddonsWithOperationsByTypes(null);
|
||||
equal(pendingAddons.length, 0);
|
||||
|
||||
uri = NetUtil.newURI(addon.iconURL);
|
||||
if (uri instanceof Ci.nsIJARURI) {
|
||||
let {file} = uri.JARFile.QueryInterface(Ci.nsIFileURL);
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
// Load XPI Provider to get schema version ID
|
||||
var XPIScope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {});
|
||||
const DB_SCHEMA = XPIScope.DB_SCHEMA;
|
||||
const {DB_SCHEMA} = XPIScope.XPIInternal;
|
||||
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user