In Android 11 wird die product
-Partition entkoppelt, sodass sie unabhängig von den Partitionen system
und vendor
ist. Im Rahmen dieser Änderungen können Sie jetzt den Zugriff der product
-Partition auf native und Java-Schnittstellen steuern. Das funktioniert ähnlich wie die Schnittstellenerzwingung für vendor
-Partitionen.
Native Schnittstellen erzwingen
Wenn Sie die Durchsetzung der nativen Schnittstelle aktivieren möchten, setzen Sie PRODUCT_PRODUCT_VNDK_VERSION
auf current
. Die Version wird automatisch auf current
festgelegt, wenn der Versand-API-Level für das Ziel höher als 29 ist. Durch die Durchsetzung sind folgende Aktionen möglich:
- Native Module in der Partition
product
, die verknüpft werden sollen:- Statisch oder dynamisch zu anderen Modulen in der
product
-Partition, die statische, gemeinsam genutzte oder Header-Bibliotheken enthalten. - Dynamisch zu VNDK-Bibliotheken in der
system
-Partition.
- Statisch oder dynamisch zu anderen Modulen in der
- JNI-Bibliotheken in nicht gebündelten APKs in der Partition
product
, die mit Bibliotheken in/product/lib
oder/product/lib64
verknüpft werden (zusätzlich zu den NDK-Bibliotheken).
Die Erzwingung erlaubt keine anderen Links zu Partitionen als zur product
-Partition.
Erzwingung der Build-Dauer (Android.bp)
In Android 11 können Systemmodule zusätzlich zu den Core- und Vendor-Bildvarianten eine Produktbildvariante erstellen. Wenn die Erzwingung nativer Schnittstellen aktiviert ist (PRODUCT_PRODUCT_VNDK_VERSION
ist auf current
gesetzt):
Native Module in der Partition
product
sind in der Produktvariante anstelle der Core-Variante enthalten.Module mit
product_available: true
in ihrenAndroid.bp
-Dateien sind für die Produktvariante verfügbar.Bibliotheken oder Binärdateien, in denen
product_specific: true
angegeben ist, können mit anderen Bibliotheken verknüpft werden, in derenAndroid.bp
-Dateienproduct_specific: true
oderproduct_available: true
angegeben ist.VNDK-Bibliotheken müssen
product_available: true
in ihrenAndroid.bp
-Dateien haben, damitproduct
-Binärdateien mit VNDK-Bibliotheken verknüpft werden können.
In der folgenden Tabelle sind die Android.bp
-Attribute zusammengefasst, die zum Erstellen von Bildvarianten verwendet werden.
Attribute in Android.bp | Erstellte Varianten | |
---|---|---|
Vor der Durchsetzung | Nach der Durchsetzung | |
Standardeinstellung (keine) | core
(einschließlich /system , /system_ext und /product ) |
core
(einschließlich /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 |
– | Kernprodukt |
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 |
Kern, Anbieter | Produkt, Anbieter |
Erzwingung der Build-Dauer (Android.mk)
Wenn die Erzwingung nativer Schnittstellen aktiviert ist, haben native Module, die in der Partition product
installiert sind, den Linktyp native:product
, der nur mit anderen native:product
- oder native:vndk
-Modulen verknüpft werden kann. Wenn Sie versuchen, Links zu anderen Modulen als diesen zu erstellen, generiert das Build-System einen Fehler bei der Überprüfung des Linktyps.
Laufzeitdurchsetzung
Wenn die Erzwingung nativer Schnittstellen aktiviert ist, lässt die Linker-Konfiguration für den Bionic-Linker nicht zu, dass Systemprozesse product
-Bibliotheken verwenden. Dadurch wird ein product
-Abschnitt für die product
-Prozesse erstellt, die nicht mit Bibliotheken außerhalb der product
-Partition verknüpft werden können. Solche Prozesse können jedoch mit VNDK-Bibliotheken verknüpft werden. Versuche, die Laufzeitlinkkonfiguration zu verletzen, führen dazu, dass der Prozess fehlschlägt und eine CANNOT LINK EXECUTABLE
-Fehlermeldung generiert wird.
Java-Schnittstellen erzwingen
Wenn Sie die Durchsetzung der Java-Schnittstelle aktivieren möchten, setzen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE
auf true
. Der Wert wird automatisch auf true
gesetzt, wenn die Versand-API-Ebene für das Ziel höher als 29 ist. Wenn die Erzwingung aktiviert ist, wird der folgende Zugriff zugelassen oder nicht:
API | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
Öffentliche API | |||||
@SystemApi | |||||
@hide API |
Wie in der Partition vendor
darf eine App oder Java-Bibliothek in der Partition product
nur öffentliche und System-APIs verwenden. Das Verknüpfen mit einer Bibliothek, die verborgene APIs verwendet, ist nicht zulässig. Diese Einschränkung umfasst das Verknüpfen zur Build-Zeit und die Reflektion zur Laufzeit.
Durchsetzung der Build-Zeit
Zur Build-Zeit prüfen Make und Soong, ob Java-Module in der Partition product
verborgene APIs verwenden. Dazu werden die Felder platform_apis
und sdk_version
geprüft. Das Feld sdk_version
von Apps in der Partition product
muss mit current
, system_current
oder der numerischen Version der API gefüllt sein und das Feld platform_apis
muss leer sein.
Laufzeitdurchsetzung
Die Android-Laufzeit prüft, ob Apps in der Partition product
keine verborgenen APIs verwenden, einschließlich Reflection. Weitere Informationen finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen.
Erzwingung der Produktschnittstelle aktivieren
Führen Sie die Schritte in diesem Abschnitt aus, um die Durchsetzung der Produktschnittstelle zu aktivieren.
Schritt | Aufgabe | Erforderlich |
---|---|---|
1 | Definieren Sie Ihr eigenes System-Makefile, in dem die Pakete für die system -Partition angegeben werden. Legen Sie dann die Anforderung für den Artefaktpfad in der device.mk fest, um zu verhindern, dass Nicht-Systemmodule in der system -Partition installiert werden. |
N |
2 | Bereinigen Sie die Zulassungsliste. | N |
3 | Native Schnittstellen erzwingen und Linkfehler zur Laufzeit erkennen (kann parallel zur Java-Durchsetzung ausgeführt werden). | J |
4 | Java-Schnittstellen erzwingen und Laufzeitverhalten prüfen (kann parallel zur nativen Erzwingung ausgeführt werden). | J |
5 | Laufzeitverhalten prüfen | J |
6 | device.mk mit der Durchsetzung der Produktschnittstelle aktualisieren |
J |
Schritt 1: Makefile erstellen und Prüfung des Artefaktpfads aktivieren
In diesem Schritt definieren Sie das system
-Makefile.
Erstellen Sie ein Makefile, in dem die Pakete für die
system
-Partition definiert werden. Erstellen Sie beispielsweise eineoem_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),)
Übernehmen Sie in der Datei
device.mk
das gemeinsame Makefiles für die Partitionsystem
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 den Artefaktpfad
Wenn PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
auf true
oder strict
festgelegt ist, verhindert das Build-System, dass Pakete, die in anderen Makefiles definiert sind, in den in require-artifacts-in-path
definierten Pfaden installiert werden und verhindert, dass Pakete, die im aktuellen Makefile definiert sind, Artefakte außerhalb der in require-artifacts-in-path
definierten Pfade installieren.
Wenn im obigen Beispiel PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
auf strict
festgelegt ist, können Makefiles außerhalb von oem_system.mk
keine Module einbinden, die auf der Partition root
oder system
installiert sind. Wenn Sie diese Module einbinden möchten, müssen Sie sie entweder in der Datei oem_system.mk
selbst oder in einer eingebundenen Make-Datei definieren.
Versuche, Module in nicht zulässigen Pfaden zu installieren, führen zu Build-Fehlern. Führen Sie einen der folgenden Schritte aus, um das Problem zu beheben:
Option 1:Das Systemmodul in die Makefiles einfügen, die in
oem_system.mk
enthalten sind. Dadurch wird die Anforderung für den Artefaktpfad erfüllt, da die Module jetzt in einer enthaltenen Make-Datei vorhanden sind. Die Installation ist also für die Pfade in „require-artifacts-in-path“ möglich.Option 2:Installieren Sie Module in der Partition
system_ext
oderproduct
(und nicht in der Partitionsystem
).Option 3:Fügen Sie dem
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
Module hinzu. Hier werden die zulässigen Module aufgeführt, die installiert werden dürfen.
Schritt 2: Zulassungsliste leeren
In diesem Schritt machen Sie PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
leer, damit alle Geräte, die oem_system.mk
gemeinsam nutzen, auch ein einzelnes system
-Bild teilen können. Wenn Sie die Liste der zulässigen Module leeren möchten, verschieben Sie alle Module in der Liste in die Partition system_ext
oder product
oder fügen Sie sie den system
-Makefiles hinzu. Dieser Schritt ist optional, da kein gemeinsames system
-Bild definiert werden muss, um die Erzwingung der Produktoberfläche zu aktivieren. Das Leeren der Zulassungsliste ist jedoch hilfreich, um die system
-Grenze mit system_ext
zu definieren.
Schritt 3: Native Schnittstellen erzwingen
In diesem Schritt legen Sie PRODUCT_PRODUCT_VNDK_VERSION := current
fest, suchen nach Build- und Laufzeitfehlern und beheben diese. So prüfen Sie den Gerätestart und die Logs und beheben Laufzeitlinkfehler:
Legen Sie
PRODUCT_PRODUCT_VNDK_VERSION := current
fest.Erstellen Sie das Gerät und suchen Sie nach Build-Fehlern. Wahrscheinlich werden einige Build-Fehler aufgrund fehlender Produktvarianten oder Kernvarianten angezeigt. Häufige Pausen sind:
hidl_interface
-Module mitproduct_specific: true
sind nicht für Systemmodule verfügbar. Ersetzen Sieproduct_specific: true
durchsystem_ext_specific: true
, um das Problem zu beheben.- In Modulen fehlt möglicherweise die für Produktmodule erforderliche Produktvariante. Um das Problem zu beheben, machen Sie das Modul für die
product
-Partition verfügbar, indem Sieproduct_available: true
festlegen, oder verschieben Sie das Modul in dieproduct
-Partition, indem Sieproduct_specific: true
festlegen.
Beheben Sie Build-Fehler und sorgen Sie dafür, dass das Gerät erfolgreich erstellt wird.
Flashen Sie das Image und suchen Sie im Geräte-Bootvorgang und in den Logs nach Laufzeitfehlern.
- Wenn das
linker
-Tag aus einem Testlaufprotokoll die MeldungCANNOT LINK EXECUTABLE
anzeigt, fehlt in der Make-Datei eine Abhängigkeit (die beim Erstellen nicht erfasst wurde). - Wenn Sie sie über das Build-System prüfen möchten, fügen Sie die erforderliche Bibliothek dem Feld
shared_libs:
oderrequired:
hinzu.
- Wenn das
Beheben Sie die fehlenden Abhängigkeiten anhand der oben genannten Anleitung.
Schritt 4: Java-Schnittstellen erzwingen
In diesem Schritt legen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
fest und beheben dann die resultierenden Build-Fehler. Achten Sie auf zwei bestimmte Arten von Fehlern:
Fehler bei Linktypen: Dieser Fehler weist darauf hin, dass eine App auf Java-Module verweist, die einen breiteren
sdk_version
haben. Um das Problem zu beheben, können Sie densdk_version
der App erweitern oder densdk_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 weist darauf hin, dass ein Symbol nicht gefunden werden kann, weil es sich in einer verborgenen API befindet. Verwenden Sie eine sichtbare (nicht ausgeblendete) API oder suchen Sie nach einer Alternative, um das Problem zu beheben. 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 sich die Laufzeit wie erwartet verhält. Bei Apps, die debugfähig sind, können Sie die Verwendung verborgener APIs mithilfe von StrictMode.detectNonSdkApiUsage
protokollieren (wodurch ein Log generiert wird, wenn die App eine verborgene API verwendet). Alternativ können Sie das Tool für statische Analysen veridex verwenden, um den Nutzungstyp (Verknüpfung oder Spiegelung), die Einschränkungsstufe 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 Verwendung von Veridex finden Sie unter Mit dem Veridex-Tool testen.
Schritt 6: „device.mk“ aktualisieren
Nachdem Sie alle Build- und Laufzeitfehler behoben und überprüft haben, dass das Laufzeitverhalten wie erwartet ist, legen Sie in device.mk
Folgendes fest:
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true