зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1363925: Part 6 - Move staged add-on install logic to XPIInstall. r=aswan
MozReview-Commit-ID: IDXsbKvl5U3 --HG-- extra : rebase_source : a17fb46c989f05c4519b9bce380d89eaca118edd extra : histedit_source : e3065c8f52311f67eefdb51b13abe26bbba9adaf
This commit is contained in:
Родитель
58a8659f77
Коммит
d099436c30
|
@ -3652,6 +3652,79 @@ var XPIInstall = {
|
|||
return addon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Completes the install of an add-on which was staged during the last
|
||||
* session.
|
||||
*
|
||||
* @param {string} id
|
||||
* The expected ID of the add-on.
|
||||
* @param {object} metadata
|
||||
* The parsed metadata for the staged install.
|
||||
* @param {InstallLocation} location
|
||||
* The install location to install the add-on to.
|
||||
* @returns {AddonInternal}
|
||||
* The installed Addon object, upon success.
|
||||
*/
|
||||
async installStagedAddon(id, metadata, location) {
|
||||
let source = getFile(`${id}.xpi`, location.getStagingDir());
|
||||
|
||||
// Check that the directory's name is a valid ID.
|
||||
if (!gIDTest.test(id) || !source.exists() || !source.isFile()) {
|
||||
throw new Error(`Ignoring invalid staging directory entry: ${id}`);
|
||||
}
|
||||
|
||||
let addon = await loadManifestFromFile(source, location);
|
||||
|
||||
if (mustSign(addon.type) &&
|
||||
addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
|
||||
throw new Error(`Refusing to install staged add-on ${id} with signed state ${addon.signedState}`);
|
||||
}
|
||||
|
||||
addon.importMetadata(metadata);
|
||||
|
||||
var oldBootstrap = null;
|
||||
logger.debug(`Processing install of ${id} in ${location.name}`);
|
||||
let existingAddon = XPIStates.findAddon(id);
|
||||
if (existingAddon && existingAddon.bootstrapped) {
|
||||
try {
|
||||
var file = existingAddon.file;
|
||||
if (file.exists()) {
|
||||
oldBootstrap = existingAddon;
|
||||
|
||||
// We'll be replacing a currently active bootstrapped add-on so
|
||||
// call its uninstall method
|
||||
let newVersion = addon.version;
|
||||
let oldVersion = existingAddon;
|
||||
let uninstallReason = newVersionReason(oldVersion, newVersion);
|
||||
|
||||
XPIProvider.callBootstrapMethod(existingAddon,
|
||||
file, "uninstall", uninstallReason,
|
||||
{ newVersion });
|
||||
XPIProvider.unloadBootstrapScope(id);
|
||||
flushChromeCaches();
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
addon._sourceBundle = location.installAddon({
|
||||
id, source, existingAddonID: id,
|
||||
});
|
||||
XPIStates.addAddon(addon);
|
||||
} catch (e) {
|
||||
if (oldBootstrap) {
|
||||
// Re-install the old add-on
|
||||
XPIProvider.callBootstrapMethod(oldBootstrap, existingAddon, "install",
|
||||
BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
return addon;
|
||||
},
|
||||
|
||||
async updateSystemAddons() {
|
||||
let systemAddonLocation = XPIProvider.installLocationsByName[KEY_APP_SYSTEM_ADDONS];
|
||||
if (!systemAddonLocation)
|
||||
|
|
|
@ -2194,83 +2194,28 @@ var XPIProvider = {
|
|||
let state = XPIStates.getLocation(location.name);
|
||||
|
||||
let cleanNames = [];
|
||||
let promises = [];
|
||||
for (let [id, metadata] of state.getStagedAddons()) {
|
||||
state.unstageAddon(id);
|
||||
|
||||
let source = getFile(`${id}.xpi`, location.getStagingDir());
|
||||
|
||||
// Check that the directory's name is a valid ID.
|
||||
if (!gIDTest.test(id) || !source.exists() || !source.isFile()) {
|
||||
logger.warn("Ignoring invalid staging directory entry: ${id}", {id});
|
||||
cleanNames.push(source.leafName);
|
||||
continue;
|
||||
}
|
||||
|
||||
changed = true;
|
||||
aManifests[location.name][id] = null;
|
||||
|
||||
let addon;
|
||||
try {
|
||||
addon = XPIInstall.syncLoadManifestFromFile(source, location);
|
||||
} catch (e) {
|
||||
logger.error(`Unable to read add-on manifest from ${source.path}`, e);
|
||||
cleanNames.push(source.leafName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mustSign(addon.type) &&
|
||||
addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
|
||||
logger.warn(`Refusing to install staged add-on ${id} with signed state ${addon.signedState}`);
|
||||
cleanNames.push(source.leafName);
|
||||
continue;
|
||||
}
|
||||
|
||||
addon.importMetadata(metadata);
|
||||
promises.push(
|
||||
XPIInstall.installStagedAddon(id, metadata, location).then(
|
||||
addon => {
|
||||
aManifests[location.name][id] = addon;
|
||||
|
||||
var oldBootstrap = null;
|
||||
logger.debug(`Processing install of ${id} in ${location.name}`);
|
||||
let existingAddon = XPIStates.findAddon(id);
|
||||
if (existingAddon && existingAddon.bootstrapped) {
|
||||
try {
|
||||
var file = existingAddon.file;
|
||||
if (file.exists()) {
|
||||
oldBootstrap = existingAddon;
|
||||
|
||||
// We'll be replacing a currently active bootstrapped add-on so
|
||||
// call its uninstall method
|
||||
let newVersion = addon.version;
|
||||
let oldVersion = existingAddon;
|
||||
let uninstallReason = XPIInstall.newVersionReason(oldVersion, newVersion);
|
||||
|
||||
this.callBootstrapMethod(existingAddon,
|
||||
file, "uninstall", uninstallReason,
|
||||
{ newVersion });
|
||||
this.unloadBootstrapScope(id);
|
||||
XPIInstall.flushChromeCaches();
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
addon._sourceBundle = location.installAddon({
|
||||
id, source, existingAddonID: id,
|
||||
});
|
||||
XPIStates.addAddon(addon);
|
||||
} catch (e) {
|
||||
logger.error("Failed to install staged add-on " + id + " in " + location.name,
|
||||
e);
|
||||
|
||||
},
|
||||
error => {
|
||||
delete aManifests[location.name][id];
|
||||
cleanNames.push(`${id}.xpi`);
|
||||
|
||||
if (oldBootstrap) {
|
||||
// Re-install the old add-on
|
||||
this.callBootstrapMethod(oldBootstrap, existingAddon, "install",
|
||||
BOOTSTRAP_REASONS.ADDON_INSTALL);
|
||||
}
|
||||
logger.error(`Failed to install staged add-on ${id} in ${location.name}`,
|
||||
error);
|
||||
}));
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
changed = true;
|
||||
awaitPromise(Promise.all(promises));
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
Загрузка…
Ссылка в новой задаче