summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/addonManager.js
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2018-02-10 04:00:58 -0500
committerMatt A. Tobin <email@mattatobin.com>2018-02-10 04:00:58 -0500
commitdeea787c2efbb9c89caec8d9efc023ffafe75613 (patch)
tree6dbe55f7d24e67ecdcc821b8c5492f6c17217852 /toolkit/mozapps/extensions/addonManager.js
parent37d5300335d81cecbecc99812747a657588c63eb (diff)
downloadUXP-deea787c2efbb9c89caec8d9efc023ffafe75613.tar
UXP-deea787c2efbb9c89caec8d9efc023ffafe75613.tar.gz
UXP-deea787c2efbb9c89caec8d9efc023ffafe75613.tar.lz
UXP-deea787c2efbb9c89caec8d9efc023ffafe75613.tar.xz
UXP-deea787c2efbb9c89caec8d9efc023ffafe75613.zip
Import Tycho's Add-on Manager
Diffstat (limited to 'toolkit/mozapps/extensions/addonManager.js')
-rw-r--r--toolkit/mozapps/extensions/addonManager.js204
1 files changed, 204 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/addonManager.js b/toolkit/mozapps/extensions/addonManager.js
new file mode 100644
index 000000000..862b1ea69
--- /dev/null
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -0,0 +1,204 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * This component serves as integration between the platform and AddonManager.
+ * It is responsible for initializing and shutting down the AddonManager as well
+ * as passing new installs from webpages to the AddonManager.
+ */
+
+"use strict";
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+const PREF_EM_UPDATE_INTERVAL = "extensions.update.interval";
+
+// The old XPInstall error codes
+const EXECUTION_ERROR = -203;
+const CANT_READ_ARCHIVE = -207;
+const USER_CANCELLED = -210;
+const DOWNLOAD_ERROR = -228;
+const UNSUPPORTED_TYPE = -244;
+const SUCCESS = 0;
+
+const MSG_INSTALL_ENABLED = "WebInstallerIsInstallEnabled";
+const MSG_INSTALL_ADDONS = "WebInstallerInstallAddonsFromWebpage";
+const MSG_INSTALL_CALLBACK = "WebInstallerInstallCallback";
+
+const CHILD_SCRIPT = "resource://gre/modules/addons/Content.js";
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+let gSingleton = null;
+
+let gParentMM = null;
+
+
+function amManager() {
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+
+ let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
+ .getService(Ci.nsIMessageListenerManager);
+ globalMM.loadFrameScript(CHILD_SCRIPT, true);
+ globalMM.addMessageListener(MSG_INSTALL_ADDONS, this);
+
+ gParentMM = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+ .getService(Ci.nsIMessageListenerManager);
+ gParentMM.addMessageListener(MSG_INSTALL_ENABLED, this);
+
+ // Needed so receiveMessage can be called directly by JS callers
+ this.wrappedJSObject = this;
+}
+
+amManager.prototype = {
+ observe: function AMC_observe(aSubject, aTopic, aData) {
+ if (aTopic == "addons-startup")
+ AddonManagerPrivate.startup();
+ },
+
+ /**
+ * @see amIAddonManager.idl
+ */
+ mapURIToAddonID: function AMC_mapURIToAddonID(uri, id) {
+ id.value = AddonManager.mapURIToAddonID(uri);
+ return !!id.value;
+ },
+
+ /**
+ * @see amIWebInstaller.idl
+ */
+ isInstallEnabled: function AMC_isInstallEnabled(aMimetype, aReferer) {
+ return AddonManager.isInstallEnabled(aMimetype);
+ },
+
+ /**
+ * @see amIWebInstaller.idl
+ */
+ installAddonsFromWebpage: function AMC_installAddonsFromWebpage(aMimetype,
+ aBrowser,
+ aInstallingPrincipal,
+ aUris, aHashes,
+ aNames, aIcons,
+ aCallback) {
+ if (aUris.length == 0)
+ return false;
+
+ let retval = true;
+ if (!AddonManager.isInstallAllowed(aMimetype, aInstallingPrincipal)) {
+ aCallback = null;
+ retval = false;
+ }
+
+ let installs = [];
+ function buildNextInstall() {
+ if (aUris.length == 0) {
+ AddonManager.installAddonsFromWebpage(aMimetype, aBrowser, aInstallingPrincipal, installs);
+ return;
+ }
+ let uri = aUris.shift();
+ AddonManager.getInstallForURL(uri, function buildNextInstall_getInstallForURL(aInstall) {
+ function callCallback(aUri, aStatus) {
+ try {
+ aCallback.onInstallEnded(aUri, aStatus);
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+ }
+
+ if (aInstall) {
+ installs.push(aInstall);
+ if (aCallback) {
+ aInstall.addListener({
+ onDownloadCancelled: function buildNextInstall_onDownloadCancelled(aInstall) {
+ callCallback(uri, USER_CANCELLED);
+ },
+
+ onDownloadFailed: function buildNextInstall_onDownloadFailed(aInstall) {
+ if (aInstall.error == AddonManager.ERROR_CORRUPT_FILE)
+ callCallback(uri, CANT_READ_ARCHIVE);
+ else
+ callCallback(uri, DOWNLOAD_ERROR);
+ },
+
+ onInstallFailed: function buildNextInstall_onInstallFailed(aInstall) {
+ callCallback(uri, EXECUTION_ERROR);
+ },
+
+ onInstallEnded: function buildNextInstall_onInstallEnded(aInstall, aStatus) {
+ callCallback(uri, SUCCESS);
+ }
+ });
+ }
+ }
+ else if (aCallback) {
+ aCallback.onInstallEnded(uri, UNSUPPORTED_TYPE);
+ }
+ buildNextInstall();
+ }, aMimetype, aHashes.shift(), aNames.shift(), aIcons.shift(), null, aBrowser);
+ }
+ buildNextInstall();
+
+ return retval;
+ },
+
+ notify: function AMC_notify(aTimer) {
+ AddonManagerPrivate.backgroundUpdateTimerHandler();
+ },
+
+ /**
+ * messageManager callback function.
+ *
+ * Listens to requests from child processes for InstallTrigger
+ * activity, and sends back callbacks.
+ */
+ receiveMessage: function AMC_receiveMessage(aMessage) {
+ let payload = aMessage.data;
+
+ switch (aMessage.name) {
+ case MSG_INSTALL_ENABLED:
+ return AddonManager.isInstallEnabled(payload.mimetype);
+
+ case MSG_INSTALL_ADDONS: {
+ let callback = null;
+ if (payload.callbackID != -1) {
+ callback = {
+ onInstallEnded: function ITP_callback(url, status) {
+ gParentMM.broadcastAsyncMessage(MSG_INSTALL_CALLBACK, {
+ callbackID: payload.callbackID,
+ url: url,
+ status: status
+ });
+ },
+ };
+ }
+
+ return this.installAddonsFromWebpage(payload.mimetype,
+ aMessage.target, payload.triggeringPrincipal, payload.uris,
+ payload.hashes, payload.names, payload.icons, callback);
+ }
+ }
+ },
+
+ classID: Components.ID("{4399533d-08d1-458c-a87a-235f74451cfa}"),
+ _xpcom_factory: {
+ createInstance: function AMC_createInstance(aOuter, aIid) {
+ if (aOuter != null)
+ throw Components.Exception("Component does not support aggregation",
+ Cr.NS_ERROR_NO_AGGREGATION);
+
+ if (!gSingleton)
+ gSingleton = new amManager();
+ return gSingleton.QueryInterface(aIid);
+ }
+ },
+ QueryInterface: XPCOMUtils.generateQI([Ci.amIAddonManager,
+ Ci.amIWebInstaller,
+ Ci.nsITimerCallback,
+ Ci.nsIObserver,
+ Ci.nsIMessageListener])
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([amManager]);