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


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

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

const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs",
});

const PERM_ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";

const MAPPED_TO_EXTENSION_PERMISSIONS = [
  "persistent-storage",
  // TODO(Bug 1336194): support geolocation manifest permission
  // (see https://bugzilla.mozilla.org/show_bug.cgi?id=1336194#c17)l
];

export class GeckoViewPermissionChild extends GeckoViewActorChild {
  getMediaPermission(aPermission) {
    return this.eventDispatcher.sendRequestForResult({
      type: "GeckoView:MediaPermission",
      ...aPermission,
    });
  }

  addCameraPermission() {
    return this.sendQuery("AddCameraPermission");
  }

  getAppPermissions(aPermissions) {
    return this.sendQuery("GetAppPermissions", aPermissions);
  }

  mediaRecordingStatusChanged(aDevices) {
    return this.eventDispatcher.sendRequest({
      type: "GeckoView:MediaRecordingStatusChanged",
      devices: aDevices,
    });
  }

  // Some WebAPI permissions can be requested and granted to extensions through the
  // the extension manifest.json, which the user have been already prompted for
  // (e.g. at install time for the one listed in the manifest.json permissions property,
  // or at runtime through the optional_permissions property and the permissions.request
  // WebExtensions API method).
  //
  // WebAPI permission that are expected to be mapped to extensions permissions are listed
  // in the MAPPED_TO_EXTENSION_PERMISSIONS array.
  //
  // @param {nsIContentPermissionType} perm
  //        The WebAPI permission being requested
  // @param {nsIContentPermissionRequest} aRequest
  //        The nsIContentPermissionRequest as received by the promptPermission method.
  //
  // @returns {null | { allow: boolean, permission: Object }
  //          Returns null if the request was not handled and should continue with the
  //          regular permission prompting flow, otherwise it returns an object to
  //          allow or disallow the permission request right away.
  checkIfGrantedByExtensionPermissions(perm, aRequest) {
    if (!aRequest.principal.addonPolicy) {
      // Not an extension, continue with the regular permission prompting flow.
      return null;
    }

    // Return earlier and continue with the regular permission prompting flow if the
    // the permission is no one that can be requested from the extension manifest file.
    if (!MAPPED_TO_EXTENSION_PERMISSIONS.includes(perm.type)) {
      return null;
    }

    // Disallow if the extension is not active anymore.
    if (!aRequest.principal.addonPolicy.active) {
      return { allow: false };
    }

    // Check if the permission have been already granted to the extension, if it is allow it right away.
    const isGranted =
      Services.perms.testPermissionFromPrincipal(
        aRequest.principal,
        perm.type
      ) === Services.perms.ALLOW_ACTION;
    if (isGranted) {
      return {
        allow: true,
        permission: { [perm.type]: Services.perms.ALLOW_ACTION },
      };
    }

    // continue with the regular permission prompting flow otherwise.
    return null;
  }

  async promptPermission(aRequest) {
    // Only allow exactly one permission request here.
    const types = aRequest.types.QueryInterface(Ci.nsIArray);
    if (types.length !== 1) {
      return { allow: false };
    }

    const perm = types.queryElementAt(0, Ci.nsIContentPermissionType);

    // Check if the request principal is an extension principal and if the permission requested
    // should be already granted based on the extension permissions (or disallowed right away
    // because the extension is not enabled anymore.
    const extensionResult = this.checkIfGrantedByExtensionPermissions(
      perm,
      aRequest
    );
    if (extensionResult) {
      return extensionResult;
    }

    if (
      perm.type === "desktop-notification" &&
      !aRequest.hasValidTransientUserGestureActivation &&
      Services.prefs.getBoolPref(
        "dom.webnotifications.requireuserinteraction",
        true
      )
    ) {
      // We need user interaction and don't have it.
      return { allow: false };
    }

    const principal =
      perm.type === "storage-access"
        ? aRequest.principal
        : aRequest.topLevelPrincipal;

    let allowOrDeny;
    try {
      allowOrDeny = await this.eventDispatcher.sendRequestForResult({
        type: "GeckoView:ContentPermission",
        uri: principal.URI.displaySpec,
        thirdPartyOrigin: aRequest.principal.origin,
        principal: lazy.E10SUtils.serializePrincipal(principal),
        perm: perm.type,
        value: perm.capability,
        contextId: principal.originAttributes.geckoViewSessionContextId ?? null,
        privateMode: principal.privateBrowsingId != 0,
      });

      if (allowOrDeny === Services.perms.ALLOW_ACTION) {
        // Ask for app permission after asking for content permission.
        if (perm.type === "geolocation") {
          const granted = await this.getAppPermissions([
            PERM_ACCESS_FINE_LOCATION,
          ]);
          allowOrDeny = granted
            ? Services.perms.ALLOW_ACTION
            : Services.perms.DENY_ACTION;
        }
      }
    } catch (error) {
      console.error("Permission error:", error);
      allowOrDeny = Services.perms.DENY_ACTION;
    }

    // Manually release the target request here to facilitate garbage collection.
    aRequest = undefined;

    const allow = allowOrDeny === Services.perms.ALLOW_ACTION;

    // The storage access code adds itself to the perm manager; no need for us to do it.
    if (perm.type === "storage-access") {
      if (allow) {
        return { allow, permission: { "storage-access": "allow" } };
      }
      return { allow };
    }

    Services.perms.addFromPrincipal(
      principal,
      perm.type,
      allowOrDeny,
      Services.perms.EXPIRE_NEVER
    );

    return { allow };
  }
}

const { debug, warn } = GeckoViewPermissionChild.initLogging(
  "GeckoViewPermissionChild"
);

[ Dauer der Verarbeitung: 0.2 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