Erzwingen von Produktpartitionsschnittstellen

Android 11 entbündelt die product - Partition, so dass es unabhängig von den system und vendor Partitionen. Im Rahmen dieser Änderungen können Sie nun das Steuer product Zugang der Partition auf native und Java - Schnittstellen (die ähnlich ist wie Schnittstelle Durchsetzung arbeitet für vendor Partitionen).

Erzwingen nativer Schnittstellen

So aktivieren Sie die native Schnittstelle Durchsetzung Satz PRODUCT_PRODUCT_VNDK_VERSION zu current . (Die Version wird automatisch auf current , wenn der Versand API - Ebene für das Ziel größer als 29) Enforcement ermöglicht:

  • Einheimische Module in der product - Partition Link:
    • Statisch oder dynamisch zu anderen Modulen in der product Partition , die statisch ist, gemeinsam genutzt oder Header - Bibliotheken.
    • Dynamisch zu VNDK Bibliotheken in der system
  • JNI Bibliotheken in entbündelten APKs in der product - Partition Link zu Bibliotheken in /product/lib oder /product/lib64 (Dies ist zusätzlich zu den NDK - Bibliotheken).

Durchsetzung erlaubt keine anderen Links zu Partitionen andere als die product - Partition.

Erzwingung der Build-Zeit (Android.bp)

In Android 11 können Systemmodule zusätzlich zu Core- und Vendor-Image-Varianten eine Produkt-Image-Variante erstellen. Wenn native Schnittstelle Durchsetzung aktiviert ist ( PRODUCT_PRODUCT_VNDK_VERSION eingestellt ist current ):

  • Einheimische Module in der product - Partition befindet sich in der Produktvariante anstelle der Kern - Variante.

  • Module mit vendor_available: true in ihren Android.bp - Dateien sind in der Produktvariante und den Lieferanten - Variante verfügbar.

  • Bibliotheken oder Binärdateien , die angeben product_specific: true kann Links zu anderen Bibliotheken , die angeben product_specific: true oder vendor_available: true in ihren Android.bp Dateien.

  • VNDK Bibliotheken müssen vendor_available: true in ihren Android.bp Dateien so product - Binärdateien VNDK Libs verknüpfen.

Die folgende Tabelle fasst die Android.bp Eigenschaften verwendet , um Bildvarianten.

Eigenschaften in Android.bp Varianten erstellt
Vor der Durchsetzung Nach der Durchsetzung
Standard (keine) Ader

(enthält /system , /system_ext und /product )

Ader

(enthält /system und /system_ext aber nicht /product )

system_ext_specific: true Ader Ader
product_specific: true Ader Produkt
vendor: true Verkäufer Verkäufer
vendor_available: true Kern, Anbieter Kern, Produkt, Anbieter
system_ext_specific: true UND vendor_available: true Kern, Anbieter Kern, Produkt, Anbieter
product_specific: true UND vendor_available: true Kern, Anbieter Produkt, Anbieter

Durchsetzung der Build-Zeit (Android.mk)

Wenn native Schnittstelle Durchsetzung aktiviert ist, nativen Module auf die installierte product Partition haben einen native:product - Link - Typ, der nur auf andere verknüpfen können native:product oder native:vndk Module. Der Versuch, eine Verbindung zu anderen Modulen als diesen herzustellen, führt dazu, dass das Build-System einen Fehler bei der Überprüfung des Verbindungstyps generiert.

Laufzeiterzwingung

Wenn native Schnittstelle Durchsetzung aktiviert ist, wird der Linker - Konfiguration für die bionischen Linker keine Systemprozesse Nutzung ermöglichen product die Schaffung eines product Abschnitt für die product , die nicht zu Bibliotheken außerhalb des verknüpfen können product - Partition (jedoch können solche Prozesse Link zu VNDK-Bibliotheken). Versuche , die Runtime - Link - Konfiguration Ursache der Prozess verletzen eine zum Scheitern verurteilt und erzeugen CANNOT LINK EXECUTABLE Fehlermeldung.

Erzwingen von Java-Schnittstellen

Um die Java - Schnittstelle Durchsetzung Set zu ermöglichen PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE zu true . (Der Wert wird automatisch auf true , wenn der Versand API - Ebene für das Ziel größer ist als 29.) Wenn diese Funktion aktiviert, Durchsetzung erlaubt / verbietet den folgenden Zugang.

API /System /system_ext /Produkt /Verkäufer /Daten
Öffentliche API
@SystemApi
@hide API

Wie in der vendor - Partition, eine App oder eine Java - Bibliothek im product ist Partition erlaubt nur öffentlichen und System - APIs zu verwenden; Das Verknüpfen mit einer Bibliothek, die versteckte APIs verwendet, ist nicht zulässig. Diese Einschränkung umfasst das Verknüpfen zur Build-Zeit und die Reflexion zur Laufzeit.

Build-Zeit-Erzwingung

Zum Zeitpunkt der Erstellung, Make und Soong überprüfen, ob Java - Module in der product - Partition nicht versteckt APIs verwenden , indem Sie die Überprüfung platform_apis und sdk_version Felder aus . Die sdk_version von Anwendungen in der product muss mit gefüllt wird current , system_current oder numerische Version der API und das platform_apis Feld leer sein muss.

Laufzeiterzwingung

Die Android - Laufzeit überprüft , dass Anwendungen in der product Partition nicht versteckt APIs verwenden, einschließlich der Reflexion. Weitere Einzelheiten finden Sie unter Einschränkungen für nicht-SDK - Schnittstellen .

Durchsetzung der Produktschnittstelle aktivieren

Verwenden Sie die Schritte in diesem Abschnitt, um die Erzwingung der Produktschnittstelle zu aktivieren.

Schritt Aufgabe Erforderlich
1 Definieren Sie Ihr eigenes System Makefile , das die Pakete für die angibt system legen Sie dann die Artefakte Pfad Anforderung Prüfung im device.mk (zur Vermeidung von Nicht - Systemmodule aus auf die Installation von system n
2 Bereinigen Sie die zulässige Liste. n
3 Erzwingen Sie native Schnittstellen und identifizieren Sie Laufzeitverknüpfungsfehler (kann parallel zur Java-Erzwingung ausgeführt werden). Ja
4 Erzwingen Sie Java-Schnittstellen und überprüfen Sie das Laufzeitverhalten (kann parallel zur nativen Durchsetzung ausgeführt werden). Ja
5 Überprüfen Sie das Laufzeitverhalten. Ja
6 Update device.mk mit Schnittstelle Durchsetzung Produkt. Ja

Schritt 1: Makefile erstellen und Artefaktpfadprüfung aktivieren

In diesem Schritt definieren Sie die system Make - Datei.

  1. Erstellen Sie eine Make - Datei, die die Pakete für das definiert system Um zum Beispiel eine erstellen oem_system.mk Datei mit folgendem:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
    
    # Applications
    PRODUCT_PACKAGES += \
        CommonSystemApp1 \
        CommonSystemApp2 \
        CommonSystemApp3 \
    
    # Binaries
    PRODUCT_PACKAGES += \
        CommonSystemBin1 \
        CommonSystemBin2 \
        CommonSystemBin3 \
    
    # Libraries
    PRODUCT_PACKAGES += \
        CommonSystemLib1 \
        CommonSystemLib2 \
        CommonSystemLib3 \
    
    PRODUCT_SYSTEM_NAME := oem_system
    PRODUCT_SYSTEM_BRAND := Android
    PRODUCT_SYSTEM_MANUFACTURER := Android
    PRODUCT_SYSTEM_MODEL := oem_system
    PRODUCT_SYSTEM_DEVICE := generic
    
    # For system-as-root devices, system.img should be mounted at /, so we
    # include ROOT here.
    _my_paths := \
     $(TARGET_COPY_OUT_ROOT)/ \
     $(TARGET_COPY_OUT_SYSTEM)/ \
    
    $(call require-artifacts-in-path, $(_my_paths),)
    
  2. In der device.mk Datei, erbt die gemeinsame Make - Datei für die system und ermöglicht das Artefakt Pfad Anforderungen überprüfen. Zum Beispiel:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk)
    
    # Enable artifact path requirements checking
    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
    

Informationen zu den Artefaktpfadanforderungen

Wenn PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS eingestellt ist true oder strict definierten die Build - System verhindert Pakete in anderen Makefiles aus definiert auf die Pfade der Installation in require-artifacts-in-path und verhindert im aktuellen Make - Datei definierten Pakete von Artefakten außerhalb der Pfade der Installation in definierten require-artifacts-in-path .

In dem obigen Beispiel mit PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS zu setzen strict , Makefiles außerhalb oem_system.mk keine Module auf die installierte umfassen kann root oder system Um auch diese Module, müssen Sie entweder definieren sie in der oem_system.mk Datei selbst oder in einer inkludierten Make - Datei. Versuche, Module auf unzulässigen Pfaden zu installieren, führen zu Build-Unterbrechungen. Um Brüche zu beheben, führen Sie einen der folgenden Schritte aus:

  • Option 1: Fügen Sie das System - Modul in dem Makefiles enthält in oem_system.mk . Dadurch wird die Artefaktpfadanforderung erfüllt (da die Module jetzt in einem enthaltenen Makefile vorhanden sind) und ermöglicht somit die Installation auf den Pfadsatz in `require-artifacts-in-path.

  • Option 2: Installieren Sie Module zum system_ext oder product - Partition (und nicht installieren Module an die system

  • Option 3: Fügen Sie Module zum PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST . Diese listet erlaubte Module auf, die installiert werden dürfen.

Schritt 2: Leeren Sie die Zulassungsliste

In diesem Schritt machen Sie die PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST leer , so dass alle Geräte freigibt oem_system.mk auch ein einzelnes teilen können system Bild. Um die erlaubten Liste zu leeren, verschieben Sie alle Module in der Liste der system_ext oder product - Partition oder fügen Sie sie auf system Make - Dateien. Dieser Schritt ist optional , da ein gemeinsames definieren system nicht aktivieren Produkt - Schnittstelle Durchsetzung erforderlich. Allerdings ist die Liste der zugelassenen Entleerung hilfreich für die Definition der system mit system_ext .

Schritt 3: Native Schnittstellen erzwingen

In diesem Schritt legen Sie PRODUCT_PRODUCT_VNDK_VERSION := current , dann suchen Sie nach Build und Laufzeitfehler und sie lösen. So überprüfen Sie den Gerätestart und die Protokolle und finden und beheben Laufzeitverknüpfungsfehler:

  1. Set PRODUCT_PRODUCT_VNDK_VERSION := current .

  2. Bauen Sie das Gerät und suchen Sie nach Build-Fehlern. Sie werden wahrscheinlich einige Build-Unterbrechungen für fehlende Produktvarianten oder Kernvarianten sehen. Zu den üblichen Pausen gehören:

    • Jede hidl_interface Modul , das hat product_specific: true nicht für Systemmodule zur Verfügung. Um dies zu beheben, ersetzen product_specific: true mit system_ext_specfic: true .
    • Modulen fehlt möglicherweise die für Produktmodule erforderliche Produktvariante. Um dies zu beheben, machen , dass Modul zur Verfügung stehende product Partition , indem vendor_available: true oder das Modul mit dem Umzug product - Partition , indem product_specific: true .
  3. Beheben Sie Buildfehler und stellen Sie sicher, dass das Gerät erfolgreich erstellt wird.

  4. Flashen Sie das Image und suchen Sie nach Laufzeitfehlern im Gerätestart und in den Protokollen.

    • Wenn der linker - Tag von einem Testfall Protokoll zeigt CANNOT LINK EXECUTABLE Nachricht, fehlt die Make - Datei eine Abhängigkeit (und nicht zum Zeitpunkt der Erstellung erfaßt).
    • Um es aus dem Build - System zu überprüfen, fügen Sie die gewünschte Bibliothek zu dem shared_libs: oder required: Feld.
  5. Lösen Sie die fehlenden Abhängigkeiten mit der oben angegebenen Anleitung.

Schritt 4: Java-Schnittstellen erzwingen

In diesem Schritt legen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true , dann finden und daraus resultierende Buildfehler zu beheben. Suchen Sie nach zwei spezifischen Arten von Fehlern:

  • Fehler beim Linktyp. Dieser Fehler zeigt an, dass eine Anwendung auf Java - Module verbindet , die ein breiteres haben sdk_version . Um dies zu beheben, können Sie die App erweitern sdk_version oder die Bibliothek beschränken sdk_version . Beispielfehler:

    error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
    
  • Symbolfehler. Dieser Fehler weist darauf hin, dass ein Symbol nicht gefunden werden kann, weil es sich in einer versteckten API befindet. Um das Problem zu beheben, verwenden Sie eine sichtbare (nicht versteckte) API oder suchen Sie nach einer Alternative. Beispielfehler:

    frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol
                ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
                                               ^
      symbol:   class ProxyAuthenticate
      location: class SipSessionGroup.SipSessionImpl
    

Schritt 5: Laufzeitverhalten prüfen

In diesem Schritt überprüfen Sie, ob das Laufzeitverhalten wie erwartet ist. Für Anwendungen , die debug sind, können Sie API - Nutzung durch log mit versteckten Monitor StrictMode.detectNonSdkApiUsage (die ein Protokoll erzeugt , wenn die App eine versteckte API verwendet). Alternativ können Sie das verwenden Veridex statische Analyse - Tool die Art der Nutzung (Verknüpfung oder Reflexion), Restriktion Ebene und Call - Stack zu erhalten.

  • Veridex-Syntax:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • Beispiel-Veridex-Ergebnis:

    #1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s):
           Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V
    
    #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
           Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
    

Einzelheiten zu Veridex Verwendung finden Sie unter Testen Sie das Veridex Werkzeug .

Schritt 6: Aktualisieren Sie device.mk

Nachdem alle Build und Laufzeitfehler Fixierung und Verifizieren , dass Laufzeitverhalten wie erwartet, setzen Sie die folgende in device.mk :

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true