From fe34974f94eb03bef7d08608785ad6dd2f841387 Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Thu, 6 May 2010 13:16:14 -0700 Subject: [PATCH] Bug 552761: Switch PFS over to the new API. r=robstrong --- .../plugins/content/pluginInstallerService.js | 151 ++++++++++-------- .../plugins/tests/browser_bug435788.js | 40 +++-- 2 files changed, 113 insertions(+), 78 deletions(-) diff --git a/toolkit/mozapps/plugins/content/pluginInstallerService.js b/toolkit/mozapps/plugins/content/pluginInstallerService.js index 8db52dcd21b..f1df560bbba 100644 --- a/toolkit/mozapps/plugins/content/pluginInstallerService.js +++ b/toolkit/mozapps/plugins/content/pluginInstallerService.js @@ -35,7 +35,13 @@ * * ***** END LICENSE BLOCK ***** */ -const nsIXPIProgressDialog = Components.interfaces.nsIXPIProgressDialog; +Components.utils.import("resource://gre/modules/AddonManager.jsm"); + +const DOWNLOAD_STARTED = 0; +const DOWNLOAD_FINISHED = 1; +const INSTALL_STARTED = 2; +const INSTALL_FINISHED = 3; +const INSTALLS_COMPLETE = 4; function getLocalizedError(key) { @@ -108,14 +114,13 @@ InstallerObserver.prototype = { this._downloader.init(this, resultFile); channel.notificationCallbacks = this; - this._fireNotification(nsIXPIProgressDialog.DOWNLOAD_START, null); + this._fireNotification(DOWNLOAD_STARTED, null); channel.asyncOpen(this._downloader, null); } catch (e) { Components.utils.reportError(e); - this._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, - getLocalizedError("error-228")); + this._fireNotification(INSTALL_FINISHED, getLocalizedError("error-228")); if (resultFile && resultFile.exists()) resultfile.remove(false); } @@ -129,7 +134,7 @@ InstallerObserver.prototype = { gPluginInstaller.pluginInstallationProgress(this._plugin.pid, aStatus, aErrorMsg); - if (aStatus == nsIXPIProgressDialog.INSTALL_DONE) { + if (aStatus == INSTALL_FINISHED) { --PluginInstallService._installersPending; PluginInstallService._fireFinishedNotification(); } @@ -158,24 +163,22 @@ InstallerObserver.prototype = { { if (!Components.isSuccessCode(status)) { // xpinstall error 228 is "Download Error" - this._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, - getLocalizedError("error-228")); + this._fireNotification(INSTALL_FINISHED, getLocalizedError("error-228")); result.remove(false); return; } - this._fireNotification(nsIXPIProgressDialog.DOWNLOAD_DONE); + this._fireNotification(DOWNLOAD_FINISHED); if (this._plugin.InstallerHash && !verifyHash(result, this._plugin.InstallerHash)) { // xpinstall error 261 is "Invalid file hash..." - this._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, - getLocalizedError("error-261")); + this._fireNotification(INSTALL_FINISHED, getLocalizedError("error-261")); result.remove(false); return; } - this._fireNotification(nsIXPIProgressDialog.INSTALL_START); + this._fireNotification(INSTALL_STARTED); result.QueryInterface(Components.interfaces.nsILocalFile); try { @@ -189,16 +192,16 @@ InstallerObserver.prototype = { observe: function(subject, topic, data) { if (topic != "process-finished") { Components.utils.reportError("Failed to launch installer"); - self._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, + self._fireNotification(INSTALL_FINISHED, getLocalizedError("error-207")); } else if (process.exitValue != 0) { Components.utils.reportError("Installer returned exit code " + process.exitValue); - self._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, + self._fireNotification(INSTALL_FINISHED, getLocalizedError("error-203")); } else { - self._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, null); + self._fireNotification(INSTALL_FINISHED, null); } result.remove(false); } @@ -206,8 +209,7 @@ InstallerObserver.prototype = { } catch (e) { Components.utils.reportError(e); - this._fireNotification(nsIXPIProgressDialog.INSTALL_DONE, - getLocalizedError("error-207")); + this._fireNotification(INSTALL_FINISHED, getLocalizedError("error-207")); result.remove(false); } }, @@ -240,20 +242,14 @@ var PluginInstallService = { aXPIPlugins) { this._xpiPlugins = aXPIPlugins; + this._xpisPending = aXPIPlugins.length; - if (this._xpiPlugins.length > 0) { - this._xpisDone = false; - - var xpiManager = Components.classes["@mozilla.org/xpinstall/install-manager;1"] - .createInstance(Components.interfaces.nsIXPInstallManager); - xpiManager.initManagerWithHashes( - [plugin.XPILocation for each (plugin in this._xpiPlugins)], - [plugin.XPIHash for each (plugin in this._xpiPlugins)], - this._xpiPlugins.length, this); - } - else { - this._xpisDone = true; - } + aXPIPlugins.forEach(function(plugin) { + AddonManager.getInstallForURL(plugin.XPILocation, function(install) { + install.addListener(PluginInstallService); + install.install(); + }, "application/x-xpinstall", plugin.XPIHash); + }); // InstallerObserver may finish immediately so we must initialise the // installers after setting the number of installers and xpis pending @@ -264,44 +260,73 @@ var PluginInstallService = { _fireFinishedNotification: function() { - if (this._installersPending == 0 && this._xpisDone) - gPluginInstaller. - pluginInstallationProgress(null, nsIXPIProgressDialog.DIALOG_CLOSE, - null); + if (this._installersPending == 0 && this._xpisPending == 0) + gPluginInstaller.pluginInstallationProgress(null, INSTALLS_COMPLETE, null); }, - // XPI progress listener stuff - onStateChange: function (aIndex, aState, aValue) - { - // get the pid to return to the wizard - var pid = this._xpiPlugins[aIndex].pid; - var errorMsg; - - if (aState == nsIXPIProgressDialog.INSTALL_DONE) { - if (aValue != 0) { - var xpinstallStrings = document.getElementById("xpinstallStrings"); - try { - errorMsg = xpinstallStrings.getString("error" + aValue); - } - catch (e) { - errorMsg = xpinstallStrings.getFormattedString("unknown.error", [aValue]); - } - } - } - - if (aState == nsIXPIProgressDialog.DIALOG_CLOSE) { - this._xpisDone = true; - this._fireFinishedNotification(); - } - else { - gPluginInstaller.pluginInstallationProgress(pid, aState, errorMsg); + getPidForInstall: function(install) { + for (let i = 0; i < this._xpiPlugins.length; i++) { + if (install.sourceURL == this._xpiPlugins[i].XPILocation) + return this._xpiPlugins[i].pid; } + return -1; }, - onProgress: function (aIndex, aValue, aMaxValue) - { - // get the pid to return to the wizard - var pid = this._xpiPlugins[aIndex].pid; - gPluginInstaller.pluginInstallationProgressMeter(pid, aValue, aMaxValue); + // InstallListener interface + onDownloadStarted: function(install) { + var pid = this.getPidForInstall(install); + gPluginInstaller.pluginInstallationProgress(pid, DOWNLOAD_STARTED, null); + }, + + onDownloadProgress: function(install) { + var pid = this.getPidForInstall(install); + gPluginInstaller.pluginInstallationProgressMeter(pid, install.progress, + install.maxProgress); + }, + + onDownloadEnded: function(install) { + var pid = this.getPidForInstall(install); + gPluginInstaller.pluginInstallationProgress(pid, DOWNLOAD_FINISHED, null); + }, + + onDownloadFailed: function(install, error) { + var pid = this.getPidForInstall(install); + switch (error) { + case AddonManager.ERROR_NETWORK_FAILURE: + var errorMsg = getLocalizedError("error-228"); + break; + case AddonManager.ERROR_INCORRECT_HASH: + var errorMsg = getLocalizedError("error-261"); + break; + case AddonManager.ERROR_CORRUPT_FILE: + var errorMsg = getLocalizedError("error-207"); + break; + } + gPluginInstaller.pluginInstallationProgress(pid, INSTALL_FINISHED, errorMsg); + + this._xpisPending--; + this._fireFinishedNotification(); + }, + + onInstallStarted: function(install) { + var pid = this.getPidForInstall(install); + gPluginInstaller.pluginInstallationProgress(pid, INSTALL_STARTED, null); + }, + + onInstallEnded: function(install, addon) { + var pid = this.getPidForInstall(install); + gPluginInstaller.pluginInstallationProgress(pid, INSTALL_FINISHED, null); + + this._xpisPending--; + this._fireFinishedNotification(); + }, + + onInstallFailed: function(install, error) { + var pid = this.getPidForInstall(install); + gPluginInstaller.pluginInstallationProgress(pid, INSTALL_FINISHED, + getLocalizedError("error-203")); + + this._xpisPending--; + this._fireFinishedNotification(); } } diff --git a/toolkit/mozapps/plugins/tests/browser_bug435788.js b/toolkit/mozapps/plugins/tests/browser_bug435788.js index 6d2152b6e12..81a8a71ef12 100644 --- a/toolkit/mozapps/plugins/tests/browser_bug435788.js +++ b/toolkit/mozapps/plugins/tests/browser_bug435788.js @@ -3,6 +3,8 @@ const Ci = Components.interfaces; const TEST_ROOT = "http://example.com/browser/toolkit/mozapps/plugins/tests/"; +Components.utils.import("resource://gre/modules/AddonManager.jsm"); + var gPrefs, gPFS, gDS, gSeenAvailable; function test() { @@ -346,15 +348,17 @@ function test_5_complete() { ok(item, "Should have seen the installed item"); is(item.status, "Installed", "Should have been a successful install"); - var em = Cc["@mozilla.org/extensions/manager;1"]. - getService(Ci.nsIExtensionManager); - ok(em.getItemForID("bug435788_1@tests.mozilla.org"), "Should have installed the extension"); - em.cancelInstallItem("bug435788_1@tests.mozilla.org"); + AddonManager.getInstalls(null, function(installs) { + is(installs.length, 1, "Should be just one install"); + is(installs[0].state, AddonManager.STATE_INSTALLED, "Should be fully installed"); + is(installs[0].addon.id, "bug435788_1@tests.mozilla.org", "Should have installed the extension"); + installs[0].cancel(); - var finish = gPFS.document.documentElement.getButton("finish"); - ok(!finish.hidden, "Finish button should not be hidden"); - ok(!finish.disabled, "Finish button should not be disabled"); - finish.click(); + var finish = gPFS.document.documentElement.getButton("finish"); + ok(!finish.hidden, "Finish button should not be hidden"); + ok(!finish.disabled, "Finish button should not be disabled"); + finish.click(); + }); } // Test a broke xpi (no install.rdf) @@ -459,10 +463,14 @@ function test_7_complete() { ok(item, "Should have seen the installed item"); is(item.status, "Failed", "Should have been a failed install"); - var em = Cc["@mozilla.org/extensions/manager;1"]. - getService(Ci.nsIExtensionManager); - ok(em.getItemForID("bug435788_1@tests.mozilla.org"), "Should have installed the extension"); - em.cancelInstallItem("bug435788_1@tests.mozilla.org"); + AddonManager.getInstalls(null, function(installs) { + is(installs.length, 4, "Should be just one install"); + is(installs[3].state, AddonManager.STATE_DOWNLOAD_FAILED, "Should have failed to download"); + is(installs[3].addon.id, "bug435788_1@tests.mozilla.org", "Should have installed the extension"); + installs[3].cancel(); + + gPFS.document.documentElement.getButton("finish").click(); + }); var finish = gPFS.document.documentElement.getButton("finish"); ok(!finish.hidden, "Finish button should not be hidden"); @@ -514,9 +522,11 @@ function test_8_complete() { ok(item, "Should have seen the installed item"); is(item.status, "Failed", "Should have not been a successful install"); - var em = Cc["@mozilla.org/extensions/manager;1"]. - getService(Ci.nsIExtensionManager); - ok(!em.getItemForID("bug435788_1@tests.mozilla.org"), "Should not have installed the extension"); + AddonManager.getInstalls(null, function(installs) { + is(installs.length, 5, "Should not be any installs"); + + gPFS.document.documentElement.getButton("finish").click(); + }); var finish = gPFS.document.documentElement.getButton("finish"); ok(!finish.hidden, "Finish button should not be hidden");