Bug 1446821: Add shutdown blocker for async extension uninstall tasks. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 18 Mar 2018 13:59:56 -0700
changeset 769174 2986a4e1e1c9deb3bc4ae38ef6fd703f273db61b
parent 769173 a8f2043af23a7a7e329a3e0418dc993e732c87fd
push id103058
push usermaglione.k@gmail.com
push dateSun, 18 Mar 2018 21:00:37 +0000
reviewersmixedpuppy
bugs1446821
milestone61.0a1
Bug 1446821: Add shutdown blocker for async extension uninstall tasks. r?mixedpuppy MozReview-Commit-ID: AMHkqviDMoV
browser/components/extensions/ext-chrome-settings-overrides.js
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionParent.jsm
--- a/browser/components/extensions/ext-chrome-settings-overrides.js
+++ b/browser/components/extensions/ext-chrome-settings-overrides.js
@@ -77,24 +77,26 @@ this.chrome_settings_overrides = class e
         Services.search.removeEngine(engine);
       } catch (e) {
         Cu.reportError(e);
       }
     }
   }
 
   static removeSearchSettings(id) {
-    this.processDefaultSearchSetting("removeSetting", id);
-    this.removeEngine(id);
+    return Promise.all([
+      this.processDefaultSearchSetting("removeSetting", id),
+      this.removeEngine(id),
+    ]);
   }
 
   static onUninstall(id) {
     // Note: We do not have to deal with homepage here as it is managed by
     // the ExtensionPreferencesManager.
-    this.removeSearchSettings(id);
+    return this.removeSearchSettings(id);
   }
 
   static onUpdate(id, manifest) {
     let haveHomepage = manifest && manifest.chrome_settings_overrides &&
                        manifest.chrome_settings_overrides.homepage;
     if (!haveHomepage) {
       ExtensionPreferencesManager.removeSetting(id, "homepage_override");
     }
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1084,17 +1084,19 @@ class ExtensionData {
 
 const PROXIED_EVENTS = new Set(["test-harness-message", "add-permissions", "remove-permissions"]);
 
 const shutdownPromises = new Map();
 
 class BootstrapScope {
   install(data, reason) {}
   uninstall(data, reason) {
-    Management.emit("uninstall", {id: data.id});
+    AsyncShutdown.profileChangeTeardown.addBlocker(
+      `Uninstalling add-on: ${data.id}`,
+      Management.emit("uninstall", {id: data.id}));
   }
 
   update(data, reason) {
     Management.emit("update", {id: data.id, resourceURI: data.resourceURI});
   }
 
   startup(data, reason) {
     // eslint-disable-next-line no-use-before-define
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -97,17 +97,17 @@ let apiManager = new class extends Schem
         module.onUpdate(id, extension.manifest);
       }));
     });
 
     this.on("uninstall", (e, {id}) => {
       let modules = this.eventModules.get("uninstall");
       return Promise.all(Array.from(modules).map(async apiName => {
         let module = await this.asyncLoadModule(apiName);
-        module.onUninstall(id);
+        return module.onUninstall(id);
       }));
     });
     /* eslint-enable mozilla/balanced-listeners */
   }
 
   getModuleJSONURLs() {
     return Array.from(XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_MODULES),
                       ([name, url]) => url);