toolkit/mozapps/extensions/addonManager.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/mozapps/extensions/addonManager.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,214 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/**
     1.9 + * This component serves as integration between the platform and AddonManager.
    1.10 + * It is responsible for initializing and shutting down the AddonManager as well
    1.11 + * as passing new installs from webpages to the AddonManager.
    1.12 + */
    1.13 +
    1.14 +"use strict";
    1.15 +
    1.16 +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
    1.17 +
    1.18 +const PREF_EM_UPDATE_INTERVAL = "extensions.update.interval";
    1.19 +
    1.20 +// The old XPInstall error codes
    1.21 +const EXECUTION_ERROR   = -203;
    1.22 +const CANT_READ_ARCHIVE = -207;
    1.23 +const USER_CANCELLED    = -210;
    1.24 +const DOWNLOAD_ERROR    = -228;
    1.25 +const UNSUPPORTED_TYPE  = -244;
    1.26 +const SUCCESS           = 0;
    1.27 +
    1.28 +const MSG_INSTALL_ENABLED  = "WebInstallerIsInstallEnabled";
    1.29 +const MSG_INSTALL_ADDONS   = "WebInstallerInstallAddonsFromWebpage";
    1.30 +const MSG_INSTALL_CALLBACK = "WebInstallerInstallCallback";
    1.31 +
    1.32 +const CHILD_SCRIPT = "resource://gre/modules/addons/Content.js";
    1.33 +
    1.34 +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    1.35 +Cu.import("resource://gre/modules/Services.jsm");
    1.36 +
    1.37 +let gSingleton = null;
    1.38 +
    1.39 +let gParentMM = null;
    1.40 +
    1.41 +
    1.42 +function amManager() {
    1.43 +  Cu.import("resource://gre/modules/AddonManager.jsm");
    1.44 +
    1.45 +  let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
    1.46 +                 .getService(Ci.nsIMessageListenerManager);
    1.47 +  globalMM.loadFrameScript(CHILD_SCRIPT, true);
    1.48 +
    1.49 +  gParentMM = Cc["@mozilla.org/parentprocessmessagemanager;1"]
    1.50 +                 .getService(Ci.nsIMessageListenerManager);
    1.51 +  gParentMM.addMessageListener(MSG_INSTALL_ENABLED, this);
    1.52 +  gParentMM.addMessageListener(MSG_INSTALL_ADDONS, this);
    1.53 +}
    1.54 +
    1.55 +amManager.prototype = {
    1.56 +  observe: function AMC_observe(aSubject, aTopic, aData) {
    1.57 +    if (aTopic == "addons-startup")
    1.58 +      AddonManagerPrivate.startup();
    1.59 +  },
    1.60 +
    1.61 +  /**
    1.62 +   * @see amIAddonManager.idl
    1.63 +   */
    1.64 +  mapURIToAddonID: function AMC_mapURIToAddonID(uri, id) {
    1.65 +    id.value = AddonManager.mapURIToAddonID(uri);
    1.66 +    return !!id.value;
    1.67 +  },
    1.68 +
    1.69 +  /**
    1.70 +   * @see amIWebInstaller.idl
    1.71 +   */
    1.72 +  isInstallEnabled: function AMC_isInstallEnabled(aMimetype, aReferer) {
    1.73 +    return AddonManager.isInstallEnabled(aMimetype);
    1.74 +  },
    1.75 +
    1.76 +  /**
    1.77 +   * @see amIWebInstaller.idl
    1.78 +   */
    1.79 +  installAddonsFromWebpage: function AMC_installAddonsFromWebpage(aMimetype,
    1.80 +                                                                  aWindow,
    1.81 +                                                                  aReferer, aUris,
    1.82 +                                                                  aHashes, aNames,
    1.83 +                                                                  aIcons, aCallback) {
    1.84 +    if (aUris.length == 0)
    1.85 +      return false;
    1.86 +
    1.87 +    let retval = true;
    1.88 +    if (!AddonManager.isInstallAllowed(aMimetype, aReferer)) {
    1.89 +      aCallback = null;
    1.90 +      retval = false;
    1.91 +    }
    1.92 +
    1.93 +    let loadGroup = null;
    1.94 +
    1.95 +    try {
    1.96 +      loadGroup = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
    1.97 +                         .getInterface(Ci.nsIWebNavigation)
    1.98 +                         .QueryInterface(Ci.nsIDocumentLoader).loadGroup;
    1.99 +    }
   1.100 +    catch (e) {
   1.101 +    }
   1.102 +
   1.103 +    let installs = [];
   1.104 +    function buildNextInstall() {
   1.105 +      if (aUris.length == 0) {
   1.106 +        AddonManager.installAddonsFromWebpage(aMimetype, aWindow, aReferer, installs);
   1.107 +        return;
   1.108 +      }
   1.109 +      let uri = aUris.shift();
   1.110 +      AddonManager.getInstallForURL(uri, function buildNextInstall_getInstallForURL(aInstall) {
   1.111 +        function callCallback(aUri, aStatus) {
   1.112 +          try {
   1.113 +            aCallback.onInstallEnded(aUri, aStatus);
   1.114 +          }
   1.115 +          catch (e) {
   1.116 +            Components.utils.reportError(e);
   1.117 +          }
   1.118 +        }
   1.119 +
   1.120 +        if (aInstall) {
   1.121 +          installs.push(aInstall);
   1.122 +          if (aCallback) {
   1.123 +            aInstall.addListener({
   1.124 +              onDownloadCancelled: function buildNextInstall_onDownloadCancelled(aInstall) {
   1.125 +                callCallback(uri, USER_CANCELLED);
   1.126 +              },
   1.127 +
   1.128 +              onDownloadFailed: function buildNextInstall_onDownloadFailed(aInstall) {
   1.129 +                if (aInstall.error == AddonManager.ERROR_CORRUPT_FILE)
   1.130 +                  callCallback(uri, CANT_READ_ARCHIVE);
   1.131 +                else
   1.132 +                  callCallback(uri, DOWNLOAD_ERROR);
   1.133 +              },
   1.134 +
   1.135 +              onInstallFailed: function buildNextInstall_onInstallFailed(aInstall) {
   1.136 +                callCallback(uri, EXECUTION_ERROR);
   1.137 +              },
   1.138 +
   1.139 +              onInstallEnded: function buildNextInstall_onInstallEnded(aInstall, aStatus) {
   1.140 +                callCallback(uri, SUCCESS);
   1.141 +              }
   1.142 +            });
   1.143 +          }
   1.144 +        }
   1.145 +        else if (aCallback) {
   1.146 +          aCallback.onInstallEnded(uri, UNSUPPORTED_TYPE);
   1.147 +        }
   1.148 +        buildNextInstall();
   1.149 +      }, aMimetype, aHashes.shift(), aNames.shift(), aIcons.shift(), null, loadGroup);
   1.150 +    }
   1.151 +    buildNextInstall();
   1.152 +
   1.153 +    return retval;
   1.154 +  },
   1.155 +
   1.156 +  notify: function AMC_notify(aTimer) {
   1.157 +    AddonManagerPrivate.backgroundUpdateCheck();
   1.158 +  },
   1.159 +
   1.160 +  /**
   1.161 +   * messageManager callback function.
   1.162 +   *
   1.163 +   * Listens to requests from child processes for InstallTrigger
   1.164 +   * activity, and sends back callbacks.
   1.165 +   */
   1.166 +  receiveMessage: function AMC_receiveMessage(aMessage) {
   1.167 +    let payload = aMessage.data;
   1.168 +    let referer = Services.io.newURI(payload.referer, null, null);
   1.169 +
   1.170 +    switch (aMessage.name) {
   1.171 +      case MSG_INSTALL_ENABLED:
   1.172 +        return this.isInstallEnabled(payload.mimetype, referer);
   1.173 +
   1.174 +      case MSG_INSTALL_ADDONS:
   1.175 +        let callback = null;
   1.176 +        if (payload.callbackID != -1) {
   1.177 +          callback = {
   1.178 +            onInstallEnded: function ITP_callback(url, status) {
   1.179 +              gParentMM.broadcastAsyncMessage(MSG_INSTALL_CALLBACK, {
   1.180 +                callbackID: payload.callbackID,
   1.181 +                url: url,
   1.182 +                status: status
   1.183 +              });
   1.184 +            },
   1.185 +          };
   1.186 +        }
   1.187 +
   1.188 +        // Should reimplement this properly with Window IDs when possible,
   1.189 +        // see bug 596109.
   1.190 +        let window = aMessage.objects.win;
   1.191 +
   1.192 +        return this.installAddonsFromWebpage(payload.mimetype,
   1.193 +          window, referer, payload.uris, payload.hashes, payload.names,
   1.194 +          payload.icons, callback);
   1.195 +    }
   1.196 +  },
   1.197 +
   1.198 +  classID: Components.ID("{4399533d-08d1-458c-a87a-235f74451cfa}"),
   1.199 +  _xpcom_factory: {
   1.200 +    createInstance: function AMC_createInstance(aOuter, aIid) {
   1.201 +      if (aOuter != null)
   1.202 +        throw Components.Exception("Component does not support aggregation",
   1.203 +                                   Cr.NS_ERROR_NO_AGGREGATION);
   1.204 +
   1.205 +      if (!gSingleton)
   1.206 +        gSingleton = new amManager();
   1.207 +      return gSingleton.QueryInterface(aIid);
   1.208 +    }
   1.209 +  },
   1.210 +  QueryInterface: XPCOMUtils.generateQI([Ci.amIAddonManager,
   1.211 +                                         Ci.amIWebInstaller,
   1.212 +                                         Ci.nsITimerCallback,
   1.213 +                                         Ci.nsIObserver,
   1.214 +                                         Ci.nsIMessageListener])
   1.215 +};
   1.216 +
   1.217 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([amManager]);

mercurial