Bug 1494215 - Show notification to allow add-on installation after xpinstallConfirm removal in bug 1473933. r=jorgk
authorGeoff Lankow <geoff@darktrojan.net>
Sat, 06 Oct 2018 11:54:57 +1300
changeset 33315 9528e42be304dc8092836f4e3897b6678b79be31
parent 33314 a87795783553295e890fdf7bacb0cb92cd24dcb8
child 33316 327ff9d24bbd68f985d92ce0890887a87057626d
push id387
push userclokep@gmail.com
push dateMon, 10 Dec 2018 21:30:47 +0000
reviewersjorgk
bugs1494215, 1473933
Bug 1494215 - Show notification to allow add-on installation after xpinstallConfirm removal in bug 1473933. r=jorgk
mail/base/content/specialTabs.js
mail/locales/en-US/chrome/messenger/messenger.properties
mail/test/mozmill/content-tabs/test-install-xpi.js
--- a/mail/base/content/specialTabs.js
+++ b/mail/base/content/specialTabs.js
@@ -1351,30 +1351,28 @@ var specialTabs = {
   observe: function (aSubject, aTopic, aData) {
     if (aTopic != "mail-startup-done")
       return;
 
     Services.obs.removeObserver(specialTabs, "mail-startup-done");
     Services.obs.addObserver(this.xpInstallObserver, "addon-install-disabled");
     Services.obs.addObserver(this.xpInstallObserver, "addon-install-blocked");
     Services.obs.addObserver(this.xpInstallObserver, "addon-install-failed");
+    Services.obs.addObserver(this.xpInstallObserver, "addon-install-confirmation");
     Services.obs.addObserver(this.xpInstallObserver, "addon-install-complete");
   },
 
   onunload: function () {
     window.removeEventListener("unload", specialTabs.onunload);
 
-    Services.obs.removeObserver(specialTabs.xpInstallObserver,
-                                "addon-install-disabled");
-    Services.obs.removeObserver(specialTabs.xpInstallObserver,
-                                "addon-install-blocked");
-    Services.obs.removeObserver(specialTabs.xpInstallObserver,
-                                "addon-install-failed");
-    Services.obs.removeObserver(specialTabs.xpInstallObserver,
-                                "addon-install-complete");
+    Services.obs.removeObserver(specialTabs.xpInstallObserver, "addon-install-disabled");
+    Services.obs.removeObserver(specialTabs.xpInstallObserver, "addon-install-blocked");
+    Services.obs.removeObserver(specialTabs.xpInstallObserver, "addon-install-failed");
+    Services.obs.removeObserver(specialTabs.xpInstallObserver, "addon-install-confirmation");
+    Services.obs.removeObserver(specialTabs.xpInstallObserver, "addon-install-complete");
   },
 
   xpInstallObserver: {
     observe: function (aSubject, aTopic, aData) {
       let brandBundle = document.getElementById("bundle_brand");
       let messengerBundle = document.getElementById("bundle_messenger");
 
       let installInfo = aSubject.wrappedJSObject;
@@ -1463,33 +1461,77 @@ var specialTabs = {
             notificationBox.appendNotification(messageString,
                                                notificationID,
                                                iconURL,
                                                notificationBox.PRIORITY_CRITICAL_HIGH,
                                                []);
           }
         }
         break;
+      case "addon-install-confirmation":
+        let acceptInstallation = () => {
+          for (let install of installInfo.installs)
+            install.install();
+          installInfo = null;
+        };
+
+        let cancelInstallation = () => {
+          if (installInfo) {
+            for (let install of installInfo.installs) {
+              // The notification may have been closed because the add-ons got
+              // cancelled elsewhere, only try to cancel those that are still
+              // pending install.
+              if (install.state != AddonManager.STATE_CANCELLED)
+                install.cancel();
+            }
+          }
+        };
+
+        messageString = messengerBundle.getString("addonConfirmInstall.message");
+        messageString = PluralForm.get(installInfo.installs.length, messageString);
+        messageString = messageString.replace("#1", brandShortName);
+        messageString = messageString.replace("#2", installInfo.installs.length);
+        messageString += " " + installInfo.installs.map(ii => ii.name).join(", ");
+
+        buttons = [{
+          label: messengerBundle.getString("addonConfirmInstall.installButton.label"),
+          accessKey: messengerBundle.getString("addonConfirmInstall.installButton.accesskey"),
+          callback: acceptInstallation,
+        }, {
+          label: messengerBundle.getString("addonConfirmInstall.cancelButton.label"),
+          accessKey: messengerBundle.getString("addonConfirmInstall.cancelButton.accesskey"),
+          callback: cancelInstallation,
+        }];
+
+        if (notificationBox)
+          notificationBox.appendNotification(messageString,
+                                             notificationID,
+                                             iconURL,
+                                             notificationBox.PRIORITY_WARNING_MEDIUM,
+                                             buttons);
+        break;
       case "addon-install-complete":
         let needsRestart = installInfo.installs.some(function(i) {
             return i.addon.pendingOperations != AddonManager.PENDING_NONE;
         });
 
         if (needsRestart) {
           messageString = messengerBundle.getString("addonsInstalledNeedsRestart");
           buttons = [{
             label: messengerBundle.getString("addonInstallRestartButton"),
             accessKey: messengerBundle.getString("addonInstallRestartButton.accesskey"),
             popup: null,
             callback: function() {
               BrowserUtils.restartApplication();
             }
           }];
-        }
-        else {
+        } else if (browser.currentURI.spec == "about:addons") {
+          messageString = messengerBundle.getString("addonsInstalled");
+          buttons = [];
+        } else {
           messageString = messengerBundle.getString("addonsInstalled");
           buttons = [{
             label: messengerBundle.getString("addonInstallManage"),
             accessKey: messengerBundle.getString("addonInstallManage.accesskey"),
             popup: null,
             callback: function() {
               // Calculate the add-on type that is most popular in the list of
               // installs.
--- a/mail/locales/en-US/chrome/messenger/messenger.properties
+++ b/mail/locales/en-US/chrome/messenger/messenger.properties
@@ -674,16 +674,27 @@ xpinstallDisabledButton.accesskey=n
 # #1 first add-on's name, #2 number of add-ons, #3 application name
 addonsInstalled=#1 has been installed successfully.;#2 add-ons have been installed successfully.
 addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-ons will be installed after you restart #3.
 addonInstallRestartButton=Restart Now
 addonInstallRestartButton.accesskey=R
 addonInstallManage=Open Add-ons Manager
 addonInstallManage.accesskey=O
 
+# LOCALIZATION NOTE (addonConfirmInstallMessage):
+# Semicolon-separated list of plural forms. See:
+# http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# #1 is brandShortName
+# #2 is the number of add-ons being installed
+addonConfirmInstall.message=Allow the installation of the following add-on in #1:;Allow the installation of the following #2 add-ons in #1:
+addonConfirmInstall.cancelButton.label=Cancel
+addonConfirmInstall.cancelButton.accesskey=C
+addonConfirmInstall.installButton.label=Install
+addonConfirmInstall.installButton.accesskey=I
+
 # LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4):
 # #1 is the add-on name, #2 is the host name, #3 is the application name
 # #4 is the application version
 addonError-1=The add-on could not be downloaded because of a connection failure on #2.
 addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
 addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
 addonError-4=#1 could not be installed because #3 cannot modify the needed file.
 
--- a/mail/test/mozmill/content-tabs/test-install-xpi.js
+++ b/mail/test/mozmill/content-tabs/test-install-xpi.js
@@ -51,27 +51,16 @@ var setupModule = function (module) {
   let wh = collector.getModule('window-helpers');
   wh.installInto(module);
   let fdh = collector.getModule('folder-display-helpers');
   fdh.installInto(module);
   let cth = collector.getModule('content-tab-helpers');
   cth.installInto(module);
 };
 
-function close_xpinstall_dialog(xpidlg) {
- xpidlg.window.document.documentElement.cancelDialog();
-}
-
-function accept_xpinstall_dialog(xpidlg) {
-  // The install dialog has a count down that we must wait for before
-  // proceeding.
-  mc.sleep(5500);
-  xpidlg.window.document.documentElement.getButton('accept').doCommand();
-}
-
 function click_notification_box_action_in_current_tab() {
   let actionButton = gNotificationBox.currentNotification.querySelector("button");
   mc.click(new elib.Elem(actionButton));
 }
 
 function close_notification_box() {
   gNotificationBox.currentNotification.close();
 }
@@ -112,24 +101,24 @@ function test_install_corrupt_xpi() {
   if (gNotificationBox.currentNotification.priority !=
       gNotificationBox.PRIORITY_CRITICAL_HIGH)
     throw new Error("Unexpected priority used for notification. Wrong Notification? Priority used was: " + gNotificationBox.currentNotification.priority);
 
   // We're done with this test, close the box.
   close_notification_box();
 }
 
-test_install_xpi_offer.__force_skip__ = true; // disabled, see bug 1494215
 function test_install_xpi_offer() {
   click_install_link_and_wait_for_alert("installlink");
 
-  // which we want to click on!
-  plan_for_modal_dialog("Addons:Install", close_xpinstall_dialog);
+  // This brings up a second notification, which we ignore.
+  AlertWatcher.planForAlert(mc);
   click_notification_box_action_in_current_tab();
-  wait_for_modal_dialog("Addons:Install", 50000);
+  AlertWatcher.waitForAlert(mc);
+  close_notification_box();
 
   // After closing the dialog we need to give just a little extra time
   // before we do things.
   mc.sleep(100);
 }
 
 function test_xpinstall_disabled() {
   Services.prefs.setBoolPref("xpinstall.enabled", false);
@@ -137,23 +126,24 @@ function test_xpinstall_disabled() {
   // Try installation again - this time we'll get an install has been disabled
   // message.
   click_install_link_and_wait_for_alert("installlink");
 
   // tell it to enable installation!
   click_notification_box_action_in_current_tab();
 }
 
-test_xpinstall_actually_install.__force_skip__ = true; // disabled, see bug 1494215
 function test_xpinstall_actually_install() {
   click_install_link_and_wait_for_alert("installlink");
 
-  // which we want to click on!
-  plan_for_modal_dialog("Addons:Install", accept_xpinstall_dialog);
-  // and this time we get an alert as well.
+  // This brings up a second notification, which we click on.
   AlertWatcher.planForAlert(mc);
   click_notification_box_action_in_current_tab();
-  wait_for_modal_dialog("Addons:Install", 50000);
+  AlertWatcher.waitForAlert(mc);
 
+  // This brings up a third notification, which we ignore.
+  AlertWatcher.planForAlert(mc);
+  click_notification_box_action_in_current_tab();
   AlertWatcher.waitForAlert(mc);
+
   close_notification_box();
   close_tab(gNewTab);
 }