Produktpartitionsoberflächen erzwingen

Android 11 entbündelt die Partition product, sodass sie unabhängig von den Partitionen system und vendor. Im Rahmen dieser Änderungen können Sie jetzt den Zugriff der Partition product auf native Schnittstellen (ähnlich der Funktionsweise der Schnittstellenerzwingung für vendor) Partitionen)

Native Oberflächen erzwingen

Legen Sie PRODUCT_PRODUCT_VNDK_VERSION fest, um die Erzwingung der nativen Schnittstelle zu aktivieren. an current. (Die Version wird beim Versand automatisch auf current das API-Level für das Ziel größer als 29 ist. Die Erzwingung ermöglicht Folgendes:

  • Zu verknüpfende native Module in der Partition product:
    • Statisch oder dynamisch zu anderen Modulen in der Partition product übertragen, statische, gemeinsam genutzte oder Header-Bibliotheken enthalten.
    • Dynamisch zu VNDK-Bibliotheken in der Partition system.
  • JNI-Bibliotheken in entbündelten APKs in der Partition product, mit denen eine Verknüpfung hergestellt werden soll Bibliotheken in /product/lib oder /product/lib64 (zusätzlich zum NDK-Bibliotheken).

Bei der Erzwingung sind nur die product-Links zu Partitionen zulässig -Partition an.

Erzwingung der Build-Dauer (Android.bp)

In Android 11 können Systemmodule Image-Variante zusätzlich zu Kern- und Anbieter-Image-Varianten hinzugefügt. Wenn nativ Schnittstellenerzwingung ist aktiviert (PRODUCT_PRODUCT_VNDK_VERSION ist auf current)

  • Native Module in der Partition product befinden sich stattdessen in der Produktvariante der Hauptvariante.

  • Module mit product_available: true in den Android.bp-Dateien sind für die Produktvariante verfügbar.

  • Bibliotheken oder Binärdateien, die product_specific: true angeben, können mit anderen Bibliotheken, die product_specific: true oder product_available: true angeben in ihren Android.bp-Dateien.

  • VNDK-Bibliotheken müssen product_available: true in den Android.bp-Dateien enthalten sodass die Binärdateien von product mit VNDK-Bibliotheken verknüpft werden können.

In der folgenden Tabelle sind die Android.bp-Attribute zusammengefasst, die zum Erstellen des Images verwendet werden Varianten.

Properties in Android.bp Erstellte Varianten
Vor der Erzwingung Nach der Erzwingung
Standardeinstellung (keine) Core
(beinhaltet /system, /system_ext und /product)
Core
(beinhaltet /system und /system_ext, aber nicht /product)
system_ext_specific: true Kern Kern
product_specific: true Kern Produkt
vendor: true Anbieter Anbieter
vendor_available: true Kern, Anbieter Kern, Anbieter
product_available: true Kern, Produkt
vendor_available: true UND product_available: true Kern, Produkt, Anbieter
system_ext_specific: true UND vendor_available: true Kern, Anbieter Kern, Anbieter
product_specific: true UND vendor_available: true Kern, Anbieter Produkt, Anbieter

Erzwingung der Build-Dauer (Android.mk)

Wenn die Erzwingung für native Anzeigen aktiviert ist, werden native Module Die Partition product hat den Verknüpfungstyp native:product, der nur verknüpft werden kann mit anderen native:product- oder native:vndk-Modulen. Es wird versucht, eine Verknüpfung zu einem beliebigen Wenn Sie andere Module verwenden, generiert das Build-System eine Linktypprüfung. Fehler.

Erzwingung der Laufzeit

Wenn die Erzwingung der nativen Schnittstelle aktiviert ist, wird die Verknüpfungskonfiguration für die bionische Verknüpfung lässt keine product-Bibliotheken zu, Erstellen eines product-Abschnitts für die product-Prozesse, der nicht verknüpft werden kann Bibliotheken außerhalb der Partition product befinden. Solche Prozesse können jedoch VNDK-Bibliotheken). Versuche, gegen die Konfiguration des Laufzeitlinks zu verstoßen, führen dazu, dass und es wird die Fehlermeldung CANNOT LINK EXECUTABLE generiert.

Java-Schnittstellen erzwingen

Um die Erzwingung der Java-Schnittstelle zu aktivieren, legen Sie Folgendes fest: PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE in true. (Der Wert ist automatisch auf true festgelegt, wenn das Versand-API-Level für das Ziel größer als 29.) Wenn diese Option aktiviert ist, wird Folgendes zugelassen oder nicht zugelassen: Zugriff:

API /system /system_ext /product /vendor /data
Öffentliche API
@SystemApi
@hide-API

Wie bei der Partition vendor kann eine Anwendung oder eine Java-Bibliothek im product Partition darf nur öffentliche APIs und System-APIs verwenden. Verknüpfung mit einer Bibliothek die versteckte APIs verwenden, dürfen nicht zulässig sein. Diese Einschränkung umfasst Verknüpfungen zum Build und Reflexion während der Laufzeit.

Erzwingung der Build-Dauer

Bei der Build-Erstellung prüft Make and Soong, ob die Java-Module im product Partition verwendet keine versteckten APIs. Prüfen Sie dazu platform_apis und sdk_version-Felder. Die sdk_version der Anwendungen in der Partition product muss mit current, system_current oder der numerischen Version der API ausgefüllt sein und Das Feld platform_apis muss leer sein.

Erzwingung der Laufzeit

Die Android-Laufzeit prüft, ob Apps in der Partition product Daten nicht nutzen versteckten APIs, einschließlich Reflexion. Weitere Informationen finden Sie unter Einschränkungen für Nicht-SDK Benutzeroberflächen.

Erzwingung der Produktoberfläche aktivieren

Führen Sie die Schritte in diesem Abschnitt aus, um die Erzwingung der Produktoberfläche zu aktivieren.

Schritt Aufgabe Erforderlich
1 Definieren Sie Ihr eigenes System-Makefile, in dem die Pakete für die system-Partition und legen Sie dann die Anforderungsprüfung für den Artefaktpfad fest im device.mk (um die Installation von Modulen zu verhindern, die nicht zum System gehören in die system-Partition ein. N
2 Bereinigen Sie die Liste der zulässigen Elemente. N
3 Erzwingen Sie native Schnittstellen und identifizieren Sie Fehler bei Laufzeitverknüpfungen (kann unter parallel zur Java-Erzwingung. J
4 Java-Schnittstellen erzwingen und Laufzeitverhalten überprüfen (kann parallel ausgeführt werden) bei nativen Anzeigen. J
5 Prüfen Sie das Laufzeitverhalten. J
6 Aktualisieren Sie device.mk mit der Erzwingung der Produktoberfläche. J

Schritt 1: Makefile erstellen und Artefaktpfadprüfung aktivieren

In diesem Schritt definieren Sie das Makefile system.

  1. Erstellen Sie ein Makefile, das die Pakete für die Partition system definiert. Für Erstellen Sie beispielsweise eine oem_system.mk-Datei mit folgendem Inhalt:

    $(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. Übernehmen Sie in der Datei device.mk das allgemeine Makefile für das system. Partitionieren und aktivieren Sie die Prüfung der Anforderungen an den Artefaktpfad. Beispiel:

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

Anforderungen an Artefaktpfade

Wenn PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS auf true oder strict gesetzt ist, das Build-System verhindert, dass in anderen Makefiles definierte Pakete installiert werden. die in require-artifacts-in-path definierten Pfade und verhindern Pakete im aktuellen Makefile durch die Installation von Artefakten außerhalb der Pfade definiert definiert in require-artifacts-in-path.

Im Beispiel oben ist PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS auf strict, Makefiles außerhalb von oem_system.mk dürfen keine Module enthalten, die installiert sind für die Partition root oder system. Um diese Module aufzunehmen, müssen Sie entweder definieren Sie sie in der oem_system.mk-Datei selbst oder in einem enthaltenen Makefile. Versuche, Module in unzulässige Pfade zu installieren, verursachen Build-Fehler. Um das Problem zu beheben führen Sie einen der folgenden Schritte aus:

  • Option 1: Fügen Sie das Systemmodul in die Makefiles Ihrer oem_system.mk Dadurch ist die Anforderung an den Artefaktpfad erfüllt (da Module jetzt in einem enthaltenen Makefile) und ermöglicht die Installation im eine Reihe von Pfaden in „require-artifacts-in-path“.

  • Option 2: Installieren Sie die Module in der Partition system_ext oder product (und Installieren Sie keine Module in der Partition system).

  • Option 3: Fügen Sie dem Modul PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST Hier werden die zulässigen Module aufgelistet zu installieren.

Schritt 2: Liste der zulässigen Elemente löschen

In diesem Schritt legen Sie den PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST fest. Leer, sodass alle Geräte, die oem_system.mk teilen, auch ein einzelnes system teilen können Bild. Zum Leeren der Liste der zulässigen Module verschieben Sie alle Module aus der Liste in den system_ext- oder product-Partition an oder fügen Sie sie zu den system-Make-Dateien hinzu. Dieses Schritt ist optional, da das Definieren eines gemeinsamen system-Images für Erzwingung der Produktoberfläche aktivieren Das Leeren der Zulassungsliste ist hilfreich, um die system-Grenze mit system_ext zu definieren.

Schritt 3: Native Oberflächen erzwingen

In diesem Schritt legen Sie PRODUCT_PRODUCT_VNDK_VERSION := current fest und sehen dann nach nach Build- und Laufzeitfehlern suchen und diese beheben. Gerätestart und Protokolle prüfen sowie Fehler bei Laufzeitverknüpfungen zu finden und zu beheben:

  1. Legen Sie PRODUCT_PRODUCT_VNDK_VERSION := current fest.

  2. Erstellen Sie das Gerät und suchen Sie nach Build-Fehlern. Sie werden wahrscheinlich einige Bauwerke sehen, Unterbrechungen bei fehlenden Produktvarianten oder Hauptvarianten. Häufige Pausen umfassen:

    • hidl_interface-Module mit product_specific: true werden nicht die für Systemmodule verfügbar sind. Ersetzen Sie product_specific: true, um das Problem zu beheben mit system_ext_specific: true.
    • In den Modulen fehlt möglicherweise die für das Produkt erforderliche Produktvariante Module. Um das Problem zu beheben, stellen Sie dieses Modul der Partition product zur Verfügung, indem Sie product_available: true einstellen oder das Modul in den product verschieben durch Festlegen von product_specific: true.
  3. Beheben Sie Build-Fehler und prüfen Sie, ob das Gerät erfolgreich erstellt werden kann.

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

    • Wenn das linker-Tag aus einem Testlauflog eine CANNOT LINK EXECUTABLE anzeigt angezeigt wird, fehlt in der Make-Datei eine Abhängigkeit (und wurde nicht Build-Dauer).
    • Fügen Sie die erforderliche Bibliothek zum shared_libs:- oder required:-Feld.
  5. Beheben Sie die fehlenden Abhängigkeiten mithilfe der obigen Anleitung.

Schritt 4: Java-Schnittstellen erzwingen

In diesem Schritt legen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true fest, finden und beheben Sie kontinuierliche Build-Fehler. Suchen Sie nach zwei bestimmten Fehlertypen:

  • Fehler beim Linktyp. Dieser Fehler gibt an, dass eine Anwendung mit Java-Modulen verknüpft ist mit einem breiteren sdk_version. Um das Problem zu beheben, sdk_version oder schränke die sdk_version der Bibliothek ein. 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 gibt an, dass ein Symbol nicht gefunden werden kann, weil in einer verborgenen API. Verwenden Sie zur Behebung des Problems eine sichtbare (nicht ausgeblendete) API oder suchen Sie nach einem als 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 prüfen Sie, ob das Laufzeitverhalten erwartungsgemäß ist. Für Apps, die Debug-fähig ist, können Sie die verborgene API-Nutzung mithilfe von Protokollen StrictMode.detectNonSdkApiUsage (generiert ein Log, wenn die App ein ausgeblendete API). Alternativ können Sie den Veridex statisches Analysetool, um die Art der Nutzung zu ermitteln (Verlinkung oder Reflexion), Einschränkungsebene und Aufrufstack.

  • Veridex-Syntax:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • Beispiel für ein 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;
    

Weitere Informationen zur Veridex-Nutzung finden Sie unter Mit Veridex testen .

Schritt 6: device.mk aktualisieren

Nach dem Beheben aller Build- und Laufzeitfehler und Überprüfen dieser Laufzeit wie erwartet, legen Sie in device.mk Folgendes fest:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true