Bug 1147808 - Cancel add-on installation when the tab or window closes while waiting for the user to confirm the installation. r=dtownsend
authorDão Gottwald <dao@mozilla.com>
Sat, 16 May 2015 13:28:34 +0200
changeset 244085 7aa664ca77c9fb1a8be4a57bd15cb110c9ca5222
parent 244084 7ac79cd0a6886ceb5ad010cfae9b36cd0ff69a56
child 244180 2f6ea66057fe37794d7fc061407495cdcece5443
push id12986
push userdgottwald@mozilla.com
push dateSat, 16 May 2015 11:28:54 +0000
treeherderfx-team@7aa664ca77c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdtownsend
bugs1147808
milestone41.0a1
Bug 1147808 - Cancel add-on installation when the tab or window closes while waiting for the user to confirm the installation. r=dtownsend
browser/base/content/browser-addons.js
browser/base/content/test/general/browser_bug553455.js
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -49,16 +49,32 @@ const gXPInstallObserver = {
     };
 
     try {
       options.displayOrigin = installInfo.originatingURI.host;
     } catch (e) {
       // originatingURI might be missing or 'host' might throw for non-nsStandardURL nsIURIs.
     }
 
+    let cancelInstallation = () => {
+      if (installInfo) {
+        for (let install of installInfo.installs)
+          install.cancel();
+      }
+
+      if (aTopic == "addon-install-confirmation")
+        this.acceptInstallation = null;
+
+      let tab = gBrowser.getTabForBrowser(browser);
+      if (tab)
+        tab.removeEventListener("TabClose", cancelInstallation);
+
+      window.removeEventListener("unload", cancelInstallation);
+    };
+
     switch (aTopic) {
     case "addon-install-disabled": {
       notificationID = "xpinstall-disabled";
 
       if (gPrefService.prefIsLocked("xpinstall.enabled")) {
         messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
         buttons = [];
       }
@@ -165,21 +181,17 @@ const gXPInstallObserver = {
       break; }
     case "addon-install-confirmation": {
       let unsigned = installInfo.installs.filter(i => i.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING);
       let someUnsigned = unsigned.length > 0 && unsigned.length < installInfo.installs.length;
 
       options.eventCallback = (aEvent) => {
         switch (aEvent) {
           case "removed":
-            if (installInfo) {
-              for (let install of installInfo.installs)
-                install.cancel();
-            }
-            this.acceptInstallation = null;
+            cancelInstallation();
             break;
           case "shown":
             let addonList = document.getElementById("addon-install-confirmation-content");
             while (addonList.firstChild)
               addonList.firstChild.remove();
 
             for (let install of installInfo.installs) {
               let container = document.createElement("hbox");
@@ -242,18 +254,22 @@ const gXPInstallObserver = {
       cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
 
       let acceptButton = document.getElementById("addon-install-confirmation-accept");
       acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
       acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
 
       let showNotification = () => {
         let tab = gBrowser.getTabForBrowser(browser);
-        if (tab)
+        if (tab) {
           gBrowser.selectedTab = tab;
+          tab.addEventListener("TabClose", cancelInstallation);
+        }
+
+        window.addEventListener("unload", cancelInstallation);
 
         if (PopupNotifications.isPanelOpen) {
           let rect = document.getElementById("addon-progress-notification").getBoundingClientRect();
           let notification = document.getElementById("addon-install-confirmation-notification");
           notification.style.minHeight = rect.height + "px";
         }
 
         PopupNotifications.show(browser, notificationID, messageString, anchorID,
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -615,16 +615,45 @@ function test_localfile() {
     var path = cr.convertChromeURL(makeURI(CHROMEROOT + "corrupt.xpi")).spec;
   } catch (ex) {
     var path = CHROMEROOT + "corrupt.xpi";
   }
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(path);
 },
 
+function test_tabclose() {
+  if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
+    runNextTest();
+    return;
+  }
+
+  // Wait for the progress notification
+  wait_for_progress_notification(aPanel => {
+    // Wait for the install confirmation dialog
+    wait_for_install_dialog(() => {
+      AddonManager.getAllInstalls(aInstalls => {
+        is(aInstalls.length, 1, "Should be one pending install");
+
+        wait_for_notification_close(() => {
+          AddonManager.getAllInstalls(aInstalls => {
+            is(aInstalls.length, 0, "Should be no pending install since the tab is closed");
+            runNextTest();
+          });
+        });
+
+        gBrowser.removeTab(gBrowser.selectedTab);
+      });
+    });
+  });
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "unsigned.xpi");
+},
+
 function test_wronghost() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.addEventListener("load", function() {
     if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
       return;
 
     gBrowser.removeEventListener("load", arguments.callee, true);