Bug 704406 - Show and hide the restart prompt when changing add-on status in about:addons [r=margaret, a=akeybl]
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 26 Mar 2012 11:16:34 -0700
changeset 91999 63c5274f27cb791e1cb05905afccdb1f740d2cea
parent 91998 af44d93f215990c37db66a6887bd13b4d1bd897e
child 92000 5c0f104db5e976e17015f37c1a9a00a2845d11a6
push idunknown
push userunknown
push dateunknown
reviewersmargaret, akeybl
bugs704406
milestone13.0a2
Bug 704406 - Show and hide the restart prompt when changing add-on status in about:addons [r=margaret, a=akeybl]
mobile/android/chrome/content/aboutAddons.js
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/aboutAddons.js
+++ b/mobile/android/chrome/content/aboutAddons.js
@@ -66,16 +66,18 @@ function showList() {
   // Hide the detail page and show the list
   let details = document.querySelector("#addons-details");
   details.style.display = "none";
   let list = document.querySelector("#addons-list");
   list.style.display = "block";
 }
 
 var Addons = {
+  _restartCount: 0,
+
   _createItem: function _createItem(aAddon) {
     let outer = document.createElement("div");
     outer.setAttribute("addonID", aAddon.id);
     outer.className = "addon-item";
     outer.setAttribute("role", "button");
     outer.addEventListener("click", function() {
       this.showDetails(outer);
       history.pushState({ id: aAddon.id }, document.title);
@@ -297,16 +299,18 @@ var Addons = {
   },
 
   setEnabled: function setEnabled(aValue, aAddon) {
     let detailItem = document.querySelector("#addons-details > .addon-item");
     let addon = aAddon || detailItem.addon;
     if (!addon)
       return;
 
+    let listItem = this._getElementForAddon(addon.id);
+
     let opType;
     if (addon.type == "search") {
       addon.engine.hidden = !aValue;
       opType = aValue ? "needs-enable" : "needs-disable";
     } else if (addon.type == "theme") {
       if (aValue) {
         // We can have only one theme enabled, so disable the current one if any
         let list = document.getElementById("addons-list");
@@ -324,33 +328,30 @@ var Addons = {
       addon.userDisabled = !aValue;
     } else {
       addon.userDisabled = !aValue;
       opType = this._getOpTypeForOperations(addon.pendingOperations);
 
       if ((addon.pendingOperations & AddonManager.PENDING_ENABLE) ||
           (addon.pendingOperations & AddonManager.PENDING_DISABLE)) {
         this.showRestart();
-      } else if (addon == detailItem.addon &&
-            detailItem.getAttribute("opType") == "needs-disable" ||
-            detailItem.getAttribute("opType") == "needs-enable") {
+      } else if (listItem && /needs-(enable|disable)/.test(listItem.getAttribute("opType"))) {
         this.hideRestart();
       }
     }
 
     if (addon == detailItem.addon) {
       detailItem.setAttribute("isDisabled", !aValue);
       if (opType)
         detailItem.setAttribute("opType", opType);
       else
         detailItem.removeAttribute("opType");
     }
 
     // Sync to the list item
-    let listItem = this._getElementForAddon(addon.id);
     if (listItem) {
       listItem.setAttribute("isDisabled", !aValue);
       if (opType)
         listItem.setAttribute("opType", opType);
       else
         listItem.removeAttribute("opType");
     }
   },
@@ -361,70 +362,75 @@ var Addons = {
 
   disable: function disable() {
     this.setEnabled(false);
   },
 
   uninstall: function uninstall() {
     let list = document.getElementById("addons-list");
     let detailItem = document.querySelector("#addons-details > .addon-item");
-    if (!detailItem.addon)
+
+    let addon = detailItem.addon;
+    if (!addon)
       return;
 
-    let listItem = this._getElementForAddon(detailItem.addon.id);
+    let listItem = this._getElementForAddon(addon.id);
 
-    if (detailItem.addon.type == "search") {
+    if (addon.type == "search") {
       // Make sure the engine isn't hidden before removing it, to make sure it's
       // visible if the user later re-adds it (works around bug 341833)
-      detailItem.addon.engine.hidden = false;
-      Services.search.removeEngine(detailItem.addon.engine);
+      addon.engine.hidden = false;
+      Services.search.removeEngine(addon.engine);
       // the search-engine-modified observer will take care of updating the list
       history.back();
     } else {
-      detailItem.addon.uninstall();
-      let opType = this._getOpTypeForOperations(detailItem.addon.pendingOperations);
-
-      if (detailItem.addon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
+      addon.uninstall();
+      if (addon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
         this.showRestart();
 
         // A disabled addon doesn't need a restart so it has no pending ops and
         // can't be cancelled
-        if (!detailItem.addon.isActive && opType == "")
+        let opType = this._getOpTypeForOperations(addon.pendingOperations);
+        if (!addon.isActive && opType == "")
           opType = "needs-uninstall";
 
         detailItem.setAttribute("opType", opType);
         listItem.setAttribute("opType", opType);
       } else {
         list.removeChild(listItem);
         history.back();
       }
     }
   },
 
   cancelUninstall: function ev_cancelUninstall() {
     let detailItem = document.querySelector("#addons-details > .addon-item");
-    if (!detailItem.addon)
+    let addon = detailItem.addon;
+    if (!addon)
       return;
 
-    detailItem.addon.cancelUninstall();
+    addon.cancelUninstall();
     this.hideRestart();
 
-    let opType = this._getOpTypeForOperations(detailItem.addon.pendingOperations);
+    let opType = this._getOpTypeForOperations(addon.pendingOperations);
     detailItem.setAttribute("opType", opType);
 
-    let listItem = this._getElementForAddon(detailItem.addon.id);
+    let listItem = this._getElementForAddon(addon.id);
     listItem.setAttribute("opType", opType);
   },
 
-  showRestart: function showRestart(aMode) {
-    // TODO (bug 704406)
+  showRestart: function showRestart() {
+    this._restartCount++;
+    gChromeWin.XPInstallObserver.showRestartPrompt();
   },
 
-  hideRestart: function hideRestart(aMode) {
-    // TODO (bug 704406)
+  hideRestart: function hideRestart() {
+    this._restartCount--;
+    if (this._restartCount == 0)
+      gChromeWin.XPInstallObserver.hideRestartPrompt();
   },
 
   onEnabled: function(aAddon) {
     let listItem = this._getElementForAddon(aAddon.id);
     if (!listItem)
       return;
 
     // Reload the details to pick up any options now that it's enabled.
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1082,21 +1082,21 @@ var NativeWindow = {
           tabID: aTabID || BrowserApp.selectedTab.id,
           options: aOptions || {}
         }
       };
       sendMessageToJava(json);
     },
 
     hide: function(aValue, aTabID) {
-      sendMessageToJava({
+      sendMessageToJava({ gecko: {
         type: "Doorhanger:Remove",
         value: aValue,
         tabID: aTabID
-      });
+      }});
     }
   },
 
   observe: function(aSubject, aTopic, aData) {
     if (aTopic == "Menu:Clicked") {
       if (this.menu._callbacks[aData])
         this.menu._callbacks[aData]();
     } else if (aTopic == "Doorhanger:Reply") {
@@ -3181,33 +3181,17 @@ var XPInstallObserver = {
   onInstallEnded: function(aInstall, aAddon) {
     let needsRestart = false;
     if (aInstall.existingAddon && (aInstall.existingAddon.pendingOperations & AddonManager.PENDING_UPGRADE))
       needsRestart = true;
     else if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL)
       needsRestart = true;
 
     if (needsRestart) {
-      let buttons = [{
-        label: Strings.browser.GetStringFromName("notificationRestart.button"),
-        callback: function() {
-          // Notify all windows that an application quit has been requested
-          let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
-          Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
-
-          // If nothing aborted, quit the app
-          if (cancelQuit.data == false) {
-            let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
-            appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
-          }
-        }
-      }];
-
-      let message = Strings.browser.GetStringFromName("notificationRestart.normal");
-      NativeWindow.doorhanger.show(message, "addon-app-restart", buttons, BrowserApp.selectedTab.id, { persistence: -1 });
+      this.showRestartPrompt();
     } else {
       let message = Strings.browser.GetStringFromName("alertAddonsInstalledNoRestart");
       NativeWindow.toast.show(message, "short");
     }
   },
 
   onInstallFailed: function(aInstall) {
     NativeWindow.toast.show(Strings.browser.GetStringFromName("alertAddonsFail"), "short");
@@ -3238,16 +3222,40 @@ var XPInstallObserver = {
     // TODO: formatStringFromName
     msg = msg.replace("#1", aInstall.name);
     if (host)
       msg = msg.replace("#2", host);
     msg = msg.replace("#3", Strings.brand.GetStringFromName("brandShortName"));
     msg = msg.replace("#4", Services.appinfo.version);
 
     NativeWindow.toast.show(msg, "short");
+  },
+
+  showRestartPrompt: function() {
+    let buttons = [{
+      label: Strings.browser.GetStringFromName("notificationRestart.button"),
+      callback: function() {
+        // Notify all windows that an application quit has been requested
+        let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
+        Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
+
+        // If nothing aborted, quit the app
+        if (cancelQuit.data == false) {
+          let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
+          appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
+        }
+      }
+    }];
+
+    let message = Strings.browser.GetStringFromName("notificationRestart.normal");
+    NativeWindow.doorhanger.show(message, "addon-app-restart", buttons, BrowserApp.selectedTab.id, { persistence: -1 });
+  },
+
+  hideRestartPrompt: function() {
+    NativeWindow.doorhanger.hide("addon-app-restart", BrowserApp.selectedTab.id);
   }
 };
 
 // Blindly copied from Safari documentation for now.
 const kViewportMinScale  = 0;
 const kViewportMaxScale  = 10;
 const kViewportMinWidth  = 200;
 const kViewportMaxWidth  = 10000;