Bug 1409245 Part 1 Move temporary addon cleanup earlier in shutdown
MozReview-Commit-ID: 7aze1AxfjlC
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -2240,23 +2240,26 @@ this.XPIProvider = {
logger.error("bootstrap startup failed", e);
AddonManagerPrivate.recordException("XPI-BOOTSTRAP", "startup failed", e);
}
// Let these shutdown a little earlier when they still have access to most
// of XPCOM
Services.obs.addObserver({
observe(aSubject, aTopic, aData) {
+ XPIProvider.cleanupTemporaryAddons();
XPIProvider._closing = true;
for (let addon of XPIProvider.sortBootstrappedAddons().reverse()) {
// If no scope has been loaded for this add-on then there is no need
// to shut it down (should only happen when a bootstrapped add-on is
// pending enable)
- if (!XPIProvider.activeAddons.has(addon.id))
+ let activeAddon = XPIProvider.activeAddons.get(addon.id);
+ if (!activeAddon || !activeAddon.started) {
continue;
+ }
// If the add-on was pending disable then shut it down and remove it
// from the persisted data.
let reason = BOOTSTRAP_REASONS.APP_SHUTDOWN;
if (addon.disable) {
reason = BOOTSTRAP_REASONS.ADDON_DISABLE;
} else if (addon.location.name == KEY_APP_TEMPORARY) {
reason = BOOTSTRAP_REASONS.ADDON_UNINSTALL;
@@ -2342,44 +2345,16 @@ this.XPIProvider = {
* 0 otherwise.
*/
async shutdown() {
logger.debug("shutdown");
// Stop anything we were doing asynchronously
this.cancelAll();
- // Uninstall any temporary add-ons.
- let tempLocation = XPIStates.getLocation(TemporaryInstallLocation.name);
- if (tempLocation) {
- for (let [id, addon] of tempLocation.entries()) {
- tempLocation.delete(id);
-
- let reason = BOOTSTRAP_REASONS.ADDON_UNINSTALL;
-
- let existing = XPIStates.findAddon(id, loc => loc != tempLocation);
- if (existing) {
- reason = newVersionReason(addon.version, existing.version);
- }
-
- this.callBootstrapMethod(addon, addon.file, "uninstall", reason);
- this.unloadBootstrapScope(id);
- TemporaryInstallLocation.uninstallAddon(id);
-
- if (existing) {
- let newAddon = XPIDatabase.makeAddonLocationVisible(id, existing.location.name);
-
- let file = new nsIFile(newAddon.path);
-
- let data = {oldVersion: addon.version};
- this.callBootstrapMethod(newAddon, file, "install", reason, data);
- }
- }
- }
-
this.activeAddons.clear();
this.allAppGlobal = true;
// If there are pending operations then we must update the list of active
// add-ons
if (Services.prefs.getBoolPref(PREF_PENDING_OPERATIONS, false)) {
AddonManagerPrivate.recordSimpleMeasure("XPIDB_pending_ops", 1);
XPIDatabase.updateActiveAddons();
@@ -2403,16 +2378,47 @@ this.XPIProvider = {
try {
await XPIDatabase.shutdown();
} catch (err) {
this._shutdownError = err;
}
},
+ cleanupTemporaryAddons() {
+ let tempLocation = XPIStates.getLocation(TemporaryInstallLocation.name);
+ if (tempLocation) {
+ for (let [id, addon] of tempLocation.entries()) {
+ tempLocation.delete(id);
+
+ let reason = BOOTSTRAP_REASONS.ADDON_UNINSTALL;
+
+ let existing = XPIStates.findAddon(id, loc => loc != tempLocation);
+ if (existing) {
+ reason = newVersionReason(addon.version, existing.version);
+ }
+
+ this.callBootstrapMethod(addon, addon.file, "shutdown", reason);
+ this.callBootstrapMethod(addon, addon.file, "uninstall", reason);
+ this.unloadBootstrapScope(id);
+ TemporaryInstallLocation.uninstallAddon(id);
+ XPIStates.removeAddon(TemporaryInstallLocation.name, id);
+
+ if (existing) {
+ let newAddon = XPIDatabase.makeAddonLocationVisible(id, existing.location.name);
+
+ let file = new nsIFile(newAddon.path);
+
+ let data = {oldVersion: addon.version};
+ this.callBootstrapMethod(newAddon, file, "install", reason, data);
+ }
+ }
+ }
+ },
+
/**
* Applies any pending theme change to the preferences.
*/
applyThemeChange() {
if (!Services.prefs.getBoolPref(PREF_SKIN_SWITCHPENDING, false))
return;
// Tell the Chrome Registry which Skin to select