Bug 624630 - [JS Error] browser_addons.js message listener is stuck and UIReadyDelayed is busted [r=me-bustage]
authorMark Finkle <mfinkle@mozilla.com>
Tue, 11 Jan 2011 00:56:29 -0500
changeset 67239 7f6d83855a0b1b781706c155a8593488a9a6a05d
parent 67238 0501ea814ad1f524b352890d1b3d15952bb0b276
child 67240 59e3fb4962afd7243dc5a1191039e4a6fe1c57e2
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme-bustage
bugs624630
Bug 624630 - [JS Error] browser_addons.js message listener is stuck and UIReadyDelayed is busted [r=me-bustage]
mobile/chrome/content/SelectHelperUI.js
mobile/chrome/content/browser-ui.js
mobile/chrome/content/extensions.js
mobile/chrome/tests/browser_addons.js
--- a/mobile/chrome/content/SelectHelperUI.js
+++ b/mobile/chrome/content/SelectHelperUI.js
@@ -104,16 +104,19 @@ var SelectHelperUI = {
     this._textbox.value = "";
   },
 
   resize: function selectHelperResize() {
     this._panel.style.maxHeight = (window.innerHeight / 1.8) + "px";
   },
 
   hide: function selectHelperResize() {
+    if (!this._list)
+      return;
+
     this.showFilter = false;
     this._container.removeEventListener("click", this, false);
     this._panel.removeEventListener("overflow", this, true);
 
     this._panel.hidden = true;
 
     if (this._docked)
       this.undock();
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -937,17 +937,17 @@ var BrowserUI = {
 
         let download = dm.getDownload(json.id);
 #ifdef ANDROID
         // since our content process doesn't have write permissions to the
         // downloads dir, we save it to the tmp dir and then move it here
         let dlFile = download.targetFile;
         if (!dlFile.exists())
           dlFile.create(file.NORMAL_FILE_TYPE, 0666);
-        let tmpDir = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);  
+        let tmpDir = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
         let tmpFile = tmpDir.clone();
         tmpFile.append(dlFile.leafName);
 
         // we sometimes race with the content process, so make sure its finished
         // creating/writing the file
         while (!tmpFile.exists());
         tmpFile.moveTo(dlFile.parent, dlFile.leafName);
 #endif
--- a/mobile/chrome/content/extensions.js
+++ b/mobile/chrome/content/extensions.js
@@ -229,21 +229,23 @@ var ExtensionsView = {
     let panels = document.getElementById("panel-items");
     panels.addEventListener("select",
                             function(aEvent) {
                               if (panels.selectedPanel.id == "addons-container")
                                 self._delayedInit();
                             },
                             false);
 
+#ifdef ANDROID
     // Hide the notification
     let alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
     let progressListener = alertsService.QueryInterface(Ci.nsIAlertsProgressListener);
     if (progressListener)
       progressListener.onCancel(ADDONS_NOTIFICATION_NAME);
+#endif
   },
 
   _delayedInit: function ev__delayedInit() {
     if (this._list)
       return;
 
     this._list = document.getElementById("addons-list");
     this._localItem = document.getElementById("addons-local");
@@ -299,17 +301,17 @@ var ExtensionsView = {
         blocked = strings.getString("addonBlocked.blocked")
         break;
       case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
         blocked = strings.getString("addonBlocked.softBlocked");
         break;
       case Ci.nsIBlocklistService.STATE_OUTDATED:
         blocked = srings.getString("addonBlocked.outdated");
         break;
-    }            
+    }
 
     let listitem = this._createItem(aAddon, "local");
     listitem.setAttribute("isDisabled", !aAddon.isActive);
     listitem.setAttribute("appDisabled", aAddon.appDisabled);
     listitem.setAttribute("appManaged", appManaged);
     listitem.setAttribute("description", aAddon.description);
     listitem.setAttribute("optionsURL", aAddon.optionsURL);
     listitem.setAttribute("opType", opType);
@@ -469,17 +471,17 @@ var ExtensionsView = {
 
       if (aItem.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 (!aItem.addon.isActive && opType == "")
           opType = "needs-uninstall";
-  
+
         aItem.setAttribute("opType", opType);
       } else {
         this._list.removeChild(aItem);
       }
     }
   },
 
   cancelUninstall: function ev_cancelUninstall(aItem) {
@@ -741,17 +743,17 @@ var ExtensionsView = {
   showMoreResults: function ev_showMoreResults(aURL) {
     if (aURL)
       BrowserUI.newTab(aURL);
   },
 
   updateAll: function ev_updateAll() {
     let aus = Cc["@mozilla.org/browser/addon-update-service;1"].getService(Ci.nsITimerCallback);
     aus.notify(null);
- 
+
     if (this._list.selectedItem)
       this._list.selectedItem.focus();
   },
 
   observe: function ev_observe(aSubject, aTopic, aData) {
     if (!document)
       return;
 
@@ -942,17 +944,17 @@ AddonInstallListener.prototype = {
 
   onInstallFailed: function(aInstall, aError) {
     this._showInstallCompleteAlert(false);
 
     if (ExtensionsView.visible) {
       let element = ExtensionsView.getElementForAddon(aInstall.sourceURI.spec);
       if (!element)
         return;
-  
+
       element.removeAttribute("opType");
       let strings = Services.strings.createBundle("chrome://global/locale/xpinstall/xpinstall.properties");
 
       let error = null;
       switch (aError) {
       case AddonManager.ERROR_NETWORK_FAILURE:
         error = "error-228";
         break;
@@ -1017,17 +1019,17 @@ AddonInstallListener.prototype = {
     }
 
     let messageString = strings.GetStringFromName(error);
     messageString = messageString.replace("#1", aInstall.name);
     if (host)
       messageString = messageString.replace("#2", host);
     messageString = messageString.replace("#3", brandShortName);
     messageString = messageString.replace("#4", Services.appinfo.version);
-    
+
     ExtensionsView.showAlert(messageString);
   },
 
   _showInstallCompleteAlert: function xpidm_showAlert(aSucceeded, aNeedsRestart) {
     let strings = Strings.browser;
     let stringName = "alertAddonsFail";
     if (aSucceeded) {
       stringName = "alertAddonsInstalled";
--- a/mobile/chrome/tests/browser_addons.js
+++ b/mobile/chrome/tests/browser_addons.js
@@ -203,17 +203,17 @@ function checkNotification(aTitle, aMess
 
   waitFor(doTest, function() { return AlertsHelper.container.hidden == false; });
 }
 
 function checkAlert(aId, aName, aLabel, aShown, aCallback) {
   let msg = null;
   if (aId)
     msg = document.getElementById(aId);
-  else 
+  else
     msg = window.getNotificationBox(gCurrentTab.browser);
   ok(!!msg, "Have notification box");
 
   let haveNotification = function(notify) {
     is(!!notify, aShown, "Notification alert exists = " + aShown);
     if (notify && aLabel)
       ok(aLabel.test(notify.label), "Notification shows correct message");
     if (aCallback)
@@ -270,55 +270,57 @@ function open_manager(aView, aCallback) 
     window.removeEventListener("ViewChanged", arguments.callee, true);
      aCallback();
   }, true);
 }
 
 function close_manager(aCallback) {
   var prefsButton = document.getElementById("tool-preferences");
   prefsButton.click();
- 
+
   ExtensionsView.clearSection();
   ExtensionsView.clearSection("local");
   ExtensionsView._list = null;
   ExtensionsView._restartCount = 0;
   BrowserUI.hidePanel();
 
   if (aCallback)
     aCallback();
 }
 
 function loadUrl(aURL, aCallback, aNewTab) {
-  messageManager.addMessageListener("pageshow", function() {
-    if (gCurrentTab.browser.currentURI.spec == aURL) {
-      messageManager.removeMessageListener("pageshow", arguments.callee);
-      if (aCallback)
-        aCallback();
-    }
-  });
   if (aNewTab)
     gCurrentTab = Browser.addTab(aURL, true);
   else
     Browser.loadURI(aURL);
+
+  gCurrentTab.browser.messageManager.addMessageListener("pageshow", function(aMessage) {
+    if (gCurrentTab.browser.currentURI.spec == aURL) {
+      gCurrentTab.browser.messageManager.removeMessageListener(aMessage.name, arguments.callee);
+      if (aCallback)
+        setTimeout(aCallback, 0);
+    }
+  });
 }
+
 function checkInstallPopup(aName, aCallback) {
   testPrompt("Installing Add-on", aName, [ {label: "Install", click: true}, {label: "Cancel", click: false}], aCallback);
 }
 
 function testPrompt(aTitle, aMessage, aButtons, aCallback) {
   function doTest() {
     let prompt = document.getElementById("prompt-confirm-dialog");
     ok(!!prompt, "Prompt shown");
 
     if (prompt) {
       let title = document.getElementById("prompt-confirm-title");
       let message = document.getElementById("prompt-confirm-message");
       is(aTitle, title.value, "Correct title shown");
       is(aMessage, message.textContent, "Correct message shown");
-  
+
      let buttons = document.getElementsByClassName("prompt-button");
       let clickButton = null;
       ok(buttons.length == aButtons.length, "Prompt has correct number of buttons");
       if (buttons.length == aButtons.length) {
         for (let i = 0; i < buttons.length; i++) {
           is(buttons[i].label, aButtons[i].label, "Button has correct label");
           if (aButtons[i].click)
             clickButton = buttons[i];
@@ -353,20 +355,20 @@ function installFromURLBar(aAddon) {
             checkInstallNotification(!aAddon.bootstrapped, function() {
               open_manager(true, function() {
                 isRestartShown(!aAddon.bootstrapped, false, function() {
                   let elt = get_addon_element(aAddon.id);
                   if (aAddon.bootstrapped) {
                     checkAddonListing(aAddon, elt, "local");
                     var button = document.getAnonymousElementByAttribute(elt, "anonid", "uninstall-button");
                     ok(!!button, "Extension has uninstall button");
-      
+
                     var updateButton = document.getElementById("addons-update-all");
                     is(updateButton.disabled, false, "Update button is enabled");
-      
+
                     ExtensionsView.uninstall(elt);
                     elt = get_addon_element(aAddon.id);
                     ok(!elt, "Addon element removed during uninstall");
                     Browser.closeTab(gCurrentTab);
                     close_manager(run_next_test);
                   } else {
                     ok(!elt, "Extension not in list");
                     AddonManager.getAllInstalls(function(aInstalls) {
@@ -478,23 +480,20 @@ updateListener.prototype = {
       case "addon-update-ended" :
         let json = aSubject.QueryInterface(Ci.nsISupportsString).data;
         let update = JSON.parse(json);
         if(update.id == this.addon.id) {
           let os = Services.obs;
           os.removeObserver(this, "addon-update-ended", false);
 
           let element = get_addon_element(update.id);
-          ok(!!element, "Have element for upgrade");  
+          ok(!!element, "Have element for upgrade");
 
           let self = this;
           isRestartShown(!this.addon.bootstrapped, true, function() {
             if(self.onComplete)
               self.onComplete();
           });
         }
         break;
     }
   },
 }
-
-
-