Produktaufteilungsoberflächen erzwingen

Unter Android 11 wird die product-Partition nicht mehr mitgeliefert. Sie ist also unabhängig von den Partitionen system und vendor. Im Rahmen dieser Änderungen können Sie jetzt den Zugriff der product-Partition auf native und Java-Schnittstellen steuern. Das funktioniert ähnlich wie die Erzwingung von Schnittstellen für vendor-Partitionen.

Native Oberflächen erzwingen

Wenn Sie die Durchsetzung der nativen Benutzeroberfläche aktivieren möchten, setzen Sie PRODUCT_PRODUCT_VNDK_VERSION auf current. (Die Version wird beim Versand automatisch auf current das API-Level für das Ziel größer als 29 ist. Durch die Erzwingung ist Folgendes möglich:

  • Zu verknüpfende native Module in der Partition product: <ph type="x-smartling-placeholder">
      </ph>
    • Statisch oder dynamisch an andere Module in der product-Partition, die statische, freigegebene 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.

Durchsetzung zur Buildzeit (Android.bp)

In Android 11 können Systemmodule zusätzlich zu Kern- und Anbieterbildvarianten eine Produktbildvariante erstellen. Wenn die Erzwingung der nativen Benutzeroberfläche aktiviert ist (PRODUCT_PRODUCT_VNDK_VERSION auf current gesetzt ist):

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

  • Module mit product_available: true in ihren 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-Properties zusammengefasst, mit denen Bildvarianten erstellt werden.

Properties in Android.bp Erstellte Varianten
Vor der Durchsetzung Nach der Erzwingung
Standardeinstellung (keine) core
(enthält /system, /system_ext und /product)
core
(enthält /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 core, vendor
product_available: true Kern, Produkt
vendor_available: true UND product_available: true core, product, vendor
system_ext_specific: true UND vendor_available: true Kern, Anbieter Kern, Anbieter
product_specific: true UND vendor_available: true core, vendor Produkt, Anbieter

Erzwingung zur Buildzeit (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.

Laufzeitdurchsetzung

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 die Erzwingung aktiviert ist, wird der folgende Zugriff zugelassen oder verhindert:

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.

Durchsetzung zur Buildzeit

Zum Zeitpunkt der Build-Phase prüfen Make und Soong, ob Java-Module in der Partition product keine versteckten APIs verwenden. Dazu werden die Felder platform_apis und sdk_version geprüft. Die sdk_version von Apps in der product-Partition muss mit current, system_current oder einer numerischen Version der API ausgefüllt sein. Das Feld platform_apis muss leer sein.

Erzwingung der Laufzeit

Die Android-Laufzeit überprüft, ob Apps in der product-Partition keine versteckten APIs verwenden, einschließlich Reflection. 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 ein eigenes System-Makefile, in dem die Pakete für die system-Partition angegeben sind, und legen Sie dann die Prüfung der Pfadvoraussetzung für Artefakte in der device.mk fest, um zu verhindern, dass nicht systemeigene Module in der system-Partition installiert werden. N
2 Bereinigen Sie die Zulassungsliste. N
3 Native Schnittstellen erzwingen und Laufzeitverknüpfungsfehler identifizieren (kann parallel zur Java-Erzwigung ausgeführt werden). 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 Prüfung des Artefaktpfads aktivieren

In diesem Schritt definieren Sie das system-Makefile.

  1. Erstellen Sie ein Makefile, das die Pakete für die Partition system definiert. 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. Erben Sie in der Datei device.mk das gemeinsame Makefile für die Partition system und aktivieren Sie die Prüfung der Anforderungen an den Pfad des Artefakts. Beispiel:

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

Anforderungen an den Pfad des Artefakts

Wenn PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS auf true oder strict festgelegt ist, verhindert das Build-System, dass in anderen Makefiles definierte Pakete in den in require-artifacts-in-path definierten Pfaden installiert werden und verhindert, dass in dem aktuellen Makefile definierte Pakete Artefakte außerhalb der in require-artifacts-in-path definierten Pfade installieren.

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. Wenn Sie diese Module einbinden möchten, müssen Sie sie entweder in der oem_system.mk-Datei selbst oder in einem eingefügten Makefile definieren. Versuche, Module in nicht zulässigen Pfaden zu installieren, führen zu Build-Unterbrechungen. So korrigieren Sie Pausen:

  • Option 1: Fügen Sie das Systemmodul in die in oem_system.mk enthaltenen Makefiles ein. Dadurch wird die Anforderung für den Pfad zum Artefakt erfüllt, da die Module jetzt in einem eingefügten Makefile vorhanden sind. So ist die Installation in den Pfaden in „require-artifacts-in-path“ möglich.

  • 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 sind die Module aufgeführt, die installiert werden dürfen.

Schritt 2: Liste der zulässigen Elemente leeren

In diesem Schritt machen Sie das PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST leer, damit alle Geräte, die oem_system.mk freigeben, auch ein einzelnes system-Bild freigeben können. Wenn Sie die Liste der zulässigen Module leeren möchten, verschieben Sie alle darin enthaltenen Module in die Partition system_ext oder product oder fügen Sie sie system-Make-Dateien hinzu. Dieser Schritt ist optional, da die Definition eines gemeinsamen system-Bilds nicht erforderlich ist, um die Erzwingung der Produktoberfläche zu 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, suchen nach Build- und Laufzeitfehlern und beheben sie. 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. Zu den häufigsten Unterbrechungen gehören:

    • hidl_interface-Module mit product_specific: true werden nicht die für Systemmodule verfügbar sind. Ersetzen Sie product_specific: true durch system_ext_specific: true, um das Problem zu beheben.
    • 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 Buildfehler und sorgen Sie dafür, dass das Gerät erfolgreich erstellt wird.

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

    • Wenn im linker-Tag eines Testfall-Logs eine CANNOT LINK EXECUTABLE-Meldung angezeigt wird, fehlt der Makefile eine Abhängigkeit und sie wurde beim Build nicht erfasst.
    • Wenn Sie die Funktion über das Build-System prüfen möchten, fügen Sie die erforderliche Bibliothek dem Feld shared_libs: oder required: hinzu.
  5. Beheben Sie die fehlenden Abhängigkeiten anhand der oben gegebenen Anleitung.

Schritt 4: Java-Schnittstellen erzwingen

In diesem Schritt legen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true fest und suchen dann nach den resultierenden Buildfehlern, die Sie beheben. 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. Sie können das Problem beheben, indem Sie den sdk_version der App erweitern oder den sdk_version der Bibliothek einschränken. Beispiele für Fehlermeldungen:

    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. Beispiele für Fehlermeldungen:

    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 den Erwartungen entspricht. Bei Apps, die debugfähig sind, können Sie die Nutzung versteckter APIs mithilfe von StrictMode.detectNonSdkApiUsage überwachen. Dadurch wird ein Log generiert, wenn die App eine versteckte API verwendet. Alternativ können Sie das statische Analysetool veridex verwenden, um die Art der Verwendung (Verknüpfung oder Reflexion), die Einschränkungsebene und den Aufrufstapel abzurufen.

  • 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

Nachdem Sie alle Build- und Laufzeitfehler behoben und überprüft haben, ob das Laufzeitverhalten wie erwartet ist, legen Sie in device.mk Folgendes fest:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true