Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  amManager.sys.mjs   Sprache: unbekannt

 
/* 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.
 */

import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";

const lazy = {};
XPCOMUtils.defineLazyPreferenceGetter(
  lazy,
  "separatePrivilegedMozillaWebContentProcess",
  "browser.tabs.remote.separatePrivilegedMozillaWebContentProcess",
  false
);
XPCOMUtils.defineLazyPreferenceGetter(
  lazy,
  "extensionsWebAPITesting",
  "extensions.webapi.testing",
  false
);

// 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_ADDON = "WebInstallerInstallAddonFromWebpage";
const MSG_INSTALL_CALLBACK = "WebInstallerInstallCallback";

const MSG_PROMISE_REQUEST = "WebAPIPromiseRequest";
const MSG_PROMISE_RESULT = "WebAPIPromiseResult";
const MSG_INSTALL_EVENT = "WebAPIInstallEvent";
const MSG_INSTALL_CLEANUP = "WebAPICleanup";
const MSG_ADDON_EVENT_REQ = "WebAPIAddonEventRequest";
const MSG_ADDON_EVENT = "WebAPIAddonEvent";

var AddonManager, AddonManagerPrivate;

export function amManager() {
  ({ AddonManager, AddonManagerPrivate } = ChromeUtils.importESModule(
    "resource://gre/modules/AddonManager.sys.mjs"
  ));

  Services.mm.addMessageListener(MSG_INSTALL_ENABLED, this);
  Services.mm.addMessageListener(MSG_PROMISE_REQUEST, this);
  Services.mm.addMessageListener(MSG_INSTALL_CLEANUP, this);
  Services.mm.addMessageListener(MSG_ADDON_EVENT_REQ, this);

  Services.ppmm.addMessageListener(MSG_INSTALL_ADDON, this);

  Services.obs.addObserver(this, "message-manager-close");
  Services.obs.addObserver(this, "message-manager-disconnect");

  AddonManager.webAPI.setEventHandler(this.sendEvent);

  // Needed so receiveMessage can be called directly by JS callers
  this.wrappedJSObject = this;
}

amManager.prototype = {
  observe(aSubject, aTopic) {
    switch (aTopic) {
      case "addons-startup":
        AddonManagerPrivate.startup();
        break;

      case "message-manager-close":
      case "message-manager-disconnect":
        this.childClosed(aSubject);
        break;
    }
  },

  installAddonFromWebpage(aPayload, aBrowser, aCallback) {
    let retval = true;

    const { mimetype, triggeringPrincipal, hash, icon, name, uri } = aPayload;

    // NOTE: consider removing this call to isInstallAllowed from here, later it is going to be called
    // again from inside AddonManager.installAddonFromWebpage as part of the block/allow logic.
    //
    // The sole purpose of the call here seems to be "clearing the optional InstallTrigger callback",
    // which seems to be actually wrong if we are still proceeding to call getInstallForURL and the same
    // logic used to block the install flow using the exact same method call later on.
    if (!AddonManager.isInstallAllowed(mimetype, triggeringPrincipal)) {
      aCallback = null;
      retval = false;
    }

    let telemetryInfo = {
      source: AddonManager.getInstallSourceFromHost(aPayload.sourceHost),
      sourceURL: aPayload.sourceURL,
    };

    if ("method" in aPayload) {
      telemetryInfo.method = aPayload.method;
    }

    AddonManager.getInstallForURL(uri, {
      hash,
      name,
      icon,
      browser: aBrowser,
      triggeringPrincipal,
      telemetryInfo,
      sendCookies: true,
    }).then(aInstall => {
      function callCallback(status) {
        try {
          aCallback?.onInstallEnded(uri, status);
        } catch (e) {
          Cu.reportError(e);
        }
      }

      if (!aInstall) {
        callCallback(UNSUPPORTED_TYPE);
        return;
      }

      if (aCallback) {
        aInstall.addListener({
          onDownloadCancelled() {
            callCallback(USER_CANCELLED);
          },

          onDownloadFailed(aInstall) {
            if (aInstall.error == AddonManager.ERROR_CORRUPT_FILE) {
              callCallback(CANT_READ_ARCHIVE);
            } else {
              callCallback(DOWNLOAD_ERROR);
            }
          },

          onInstallFailed() {
            callCallback(EXECUTION_ERROR);
          },

          onInstallEnded() {
            callCallback(SUCCESS);
          },
        });
      }

      AddonManager.installAddonFromWebpage(
        mimetype,
        aBrowser,
        triggeringPrincipal,
        aInstall,
        {
          hasCrossOriginAncestor: aPayload.hasCrossOriginAncestor,
        }
      );
    });

    return retval;
  },

  notify() {
    AddonManagerPrivate.backgroundUpdateTimerHandler();
  },

  // Maps message manager instances for content processes to the associated
  // AddonListener instances.
  addonListeners: new Map(),

  _addAddonListener(target) {
    if (!this.addonListeners.has(target)) {
      let handler = (event, id) => {
        target.sendAsyncMessage(MSG_ADDON_EVENT, { event, id });
      };
      let listener = {
        onEnabling: addon => handler("onEnabling", addon.id),
        onEnabled: addon => handler("onEnabled", addon.id),
        onDisabling: addon => handler("onDisabling", addon.id),
        onDisabled: addon => handler("onDisabled", addon.id),
        onInstalling: addon => handler("onInstalling", addon.id),
        onInstalled: addon => handler("onInstalled", addon.id),
        onUninstalling: addon => handler("onUninstalling", addon.id),
        onUninstalled: addon => handler("onUninstalled", addon.id),
        onOperationCancelled: addon =>
          handler("onOperationCancelled", addon.id),
      };
      this.addonListeners.set(target, listener);
      AddonManager.addAddonListener(listener);
    }
  },

  _removeAddonListener(target) {
    if (this.addonListeners.has(target)) {
      AddonManager.removeAddonListener(this.addonListeners.get(target));
      this.addonListeners.delete(target);
    }
  },

  /**
   * messageManager callback function.
   *
   * Listens to requests from child processes for InstallTrigger
   * activity, and sends back callbacks.
   */
  receiveMessage(aMessage) {
    let payload = aMessage.data;

    switch (aMessage.name) {
      case MSG_INSTALL_ENABLED:
        return AddonManager.isInstallEnabled(payload.mimetype);

      case MSG_INSTALL_ADDON: {
        let browser = payload.browsingContext.top.embedderElement;

        let callback = null;
        if (payload.callbackID != -1) {
          let mm = browser.messageManager;
          callback = {
            onInstallEnded(url, status) {
              mm.sendAsyncMessage(MSG_INSTALL_CALLBACK, {
                callbackID: payload.callbackID,
                url,
                status,
              });
            },
          };
        }

        return this.installAddonFromWebpage(payload, browser, callback);
      }

      case MSG_PROMISE_REQUEST: {
        if (
          !lazy.extensionsWebAPITesting &&
          lazy.separatePrivilegedMozillaWebContentProcess &&
          aMessage.target &&
          aMessage.target.remoteType != null &&
          aMessage.target.remoteType !== "privilegedmozilla"
        ) {
          return undefined;
        }

        let mm = aMessage.target.messageManager;
        let resolve = value => {
          mm.sendAsyncMessage(MSG_PROMISE_RESULT, {
            callbackID: payload.callbackID,
            resolve: value,
          });
        };
        let reject = value => {
          mm.sendAsyncMessage(MSG_PROMISE_RESULT, {
            callbackID: payload.callbackID,
            reject: value,
          });
        };

        let API = AddonManager.webAPI;
        if (payload.type in API) {
          API[payload.type](aMessage.target, ...payload.args).then(
            resolve,
            reject
          );
        } else {
          reject("Unknown Add-on API request.");
        }
        break;
      }

      case MSG_INSTALL_CLEANUP: {
        if (
          !lazy.extensionsWebAPITesting &&
          lazy.separatePrivilegedMozillaWebContentProcess &&
          aMessage.target &&
          aMessage.target.remoteType != null &&
          aMessage.target.remoteType !== "privilegedmozilla"
        ) {
          return undefined;
        }

        AddonManager.webAPI.clearInstalls(payload.ids);
        break;
      }

      case MSG_ADDON_EVENT_REQ: {
        if (
          !lazy.extensionsWebAPITesting &&
          lazy.separatePrivilegedMozillaWebContentProcess &&
          aMessage.target &&
          aMessage.target.remoteType != null &&
          aMessage.target.remoteType !== "privilegedmozilla"
        ) {
          return undefined;
        }

        let target = aMessage.target.messageManager;
        if (payload.enabled) {
          this._addAddonListener(target);
        } else {
          this._removeAddonListener(target);
        }
      }
    }
    return undefined;
  },

  childClosed(target) {
    AddonManager.webAPI.clearInstallsFrom(target);
    this._removeAddonListener(target);
  },

  sendEvent(mm, data) {
    mm.sendAsyncMessage(MSG_INSTALL_EVENT, data);
  },

  classID: Components.ID("{4399533d-08d1-458c-a87a-235f74451cfa}"),
  QueryInterface: ChromeUtils.generateQI(["nsITimerCallback", "nsIObserver"]),
};

const BLOCKLIST_SYS_MJS = "resource://gre/modules/Blocklist.sys.mjs";
ChromeUtils.defineESModuleGetters(lazy, { Blocklist: BLOCKLIST_SYS_MJS });

export function BlocklistService() {
  this.wrappedJSObject = this;
}

BlocklistService.prototype = {
  STATE_NOT_BLOCKED: Ci.nsIBlocklistService.STATE_NOT_BLOCKED,
  STATE_SOFTBLOCKED: Ci.nsIBlocklistService.STATE_SOFTBLOCKED,
  STATE_BLOCKED: Ci.nsIBlocklistService.STATE_BLOCKED,

  get isLoaded() {
    return Cu.isESModuleLoaded(BLOCKLIST_SYS_MJS) && lazy.Blocklist.isLoaded;
  },

  observe(...args) {
    return lazy.Blocklist.observe(...args);
  },

  notify() {
    lazy.Blocklist.notify();
  },

  classID: Components.ID("{66354bc9-7ed1-4692-ae1d-8da97d6b205e}"),
  QueryInterface: ChromeUtils.generateQI([
    "nsIObserver",
    "nsIBlocklistService",
    "nsITimerCallback",
  ]),
};

[ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge