Bug 1409245 Part 1 Move temporary addon cleanup earlier in shutdown draft
authorAndrew Swan <aswan@mozilla.com>
Sat, 21 Oct 2017 15:36:59 -0700
changeset 689493 6b95e1d859c4533ce353c2ac13220bc4fdcd0a31
parent 685447 967c95cee709756596860ed2a3e6ac06ea3a053f
child 689494 aa76ce45d5c249685cb65345c4c4d99277b0e3f9
push id87036
push useraswan@mozilla.com
push dateTue, 31 Oct 2017 16:41:42 +0000
bugs1409245
milestone58.0a1
Bug 1409245 Part 1 Move temporary addon cleanup earlier in shutdown MozReview-Commit-ID: 7aze1AxfjlC
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- 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