Android 11 entbündelt die Partition product
und ist somit 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 automatisch auf current
gesetzt, wenn die API-Version für das Ziel höher als 29 ist. Durch die Erzwingung ist Folgendes möglich:
- Native Module in der Partition
product
, die verknüpft werden sollen:- Statisch oder dynamisch an andere Module in der
product
-Partition, die statische, freigegebene oder Header-Bibliotheken enthalten. - Dynamisch zu VNDK-Bibliotheken in der
system
-Partition.
- Statisch oder dynamisch an andere Module 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 sollen (zusätzlich zu den NDK-Bibliotheken)
Die Erzwingung lässt außer der Partition product
keine anderen Links zu Partitionen zu.
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
product
-Partition befinden sich in der Produktvariante und nicht in der Kernvariante.Module mit
product_available: true
in ihrenAndroid.bp
-Dateien sind für die Produktvariante verfügbar.Bibliotheken oder Binärdateien, die
product_specific: true
angeben, können mit anderen Bibliotheken verknüpft werden, dieproduct_specific: true
oderproduct_available: true
in ihrenAndroid.bp
-Dateien angeben.VNDK-Bibliotheken müssen
product_available: true
in ihrenAndroid.bp
-Dateien enthalten, 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 Image-Varianten verwendet werden.
Properties in Android.bp | Erstellte Varianten | |
---|---|---|
Vor der Erzwingung | Nach der Durchsetzung | |
Standardeinstellung (kein) | 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 |
core, vendor | 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 | core, vendor |
product_specific: true UND vendor_available:
true |
Kern, Anbieter | Produkt, Anbieter |
Erzwingung zur Buildzeit (Android.mk)
Wenn die Erzwingung der nativen Schnittstelle 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, eine Verknüpfung mit anderen Modulen herzustellen, generiert das Build-System einen Fehler bei der Linktypprüfung.
Laufzeitdurchsetzung
Wenn die Erzwingung der nativen Schnittstelle aktiviert ist, erlaubt die Linker-Konfiguration für den Bionic-Linker Systemprozessen nicht, product
-Bibliotheken zu verwenden. Es 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, gegen die Laufzeitverknüpfungskonfiguration zu verstoßen, führen dazu, dass der Vorgang fehlschlägt und eine CANNOT LINK EXECUTABLE
-Fehlermeldung generiert wird.
Java-Schnittstellen erzwingen
Wenn Sie die Durchsetzung der Java-Oberfläche 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 über 29 liegt. Wenn die Erzwingung aktiviert ist, wird der folgende Zugriff zugelassen oder verhindert:
API | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
Public API | |||||
@SystemApi | |||||
@hide-API |
Wie in der Partition vendor
dürfen Apps oder Java-Bibliotheken in der Partition product
nur öffentliche und System-APIs verwenden. Verknüpfungen mit einer Bibliothek, die versteckte APIs verwendet, sind nicht zulässig. Diese Einschränkung umfasst die Verknüpfung zum Build-Zeitpunkt und die 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
der Anwendungen in der Partition product
muss mit current
, system_current
oder der numerischen Version der API ausgefüllt werden und das Feld platform_apis
muss leer sein.
Laufzeitdurchsetzung
Die Android-Laufzeit prü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-Schnittstellen.
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 Partition system 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 Partition system 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 prüfen (kann parallel zur nativen Erzwingung ausgeführt werden) | 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 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 Makefile für die Partitionsystem
und aktivieren Sie die Prüfung der Anforderungen für 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 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 der aktuellen Makefile definierte Pakete Artefakte außerhalb der in require-artifacts-in-path
definierten Pfade installieren.
Im obigen Beispiel, wobei PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
auf strict
gesetzt ist, können Makefiles außerhalb von oem_system.mk
keine Module enthalten, die in der Partition root
oder system
installiert sind. Wenn du diese Module einbinden möchtest, musst du sie entweder in der Datei oem_system.mk
selbst oder in einem enthaltenen 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 Makefiles in
oem_system.mk
ein. Dadurch wird die Anforderung an den Artefaktpfad erfüllt (da die Module jetzt in einem enthaltenen Makefile vorhanden sind) und die Installation in der Gruppe von Pfaden in „require-artifacts-in-path“ möglich.Option 2:Installieren Sie Module in der Partition
system_ext
oderproduct
, aber nicht in der Partitionsystem
.Option 3:Dem
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
Module hinzufügen Hier sind die Module aufgeführt, die installiert werden dürfen.
Schritt 2: Zugelassene Liste 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. Zum Leeren der Liste der zulässigen Module verschieben Sie alle Module in der Liste in die Partition system_ext
oder product
oder fügen sie den Erstellungsdateien system
hinzu. Dieser Schritt ist optional, da das Definieren eines gemeinsamen system
-Images nicht erforderlich ist, um die Erzwingung der Produktoberfläche zu aktivieren. Es ist jedoch hilfreich, die Zulassungsliste zu leeren, 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. So prüfen Sie den Gerätestart und die Logs sowie Fehler bei Laufzeitverknüpfungen und beheben diese:
Legen Sie
PRODUCT_PRODUCT_VNDK_VERSION := current
fest.Erstellen 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 häufigsten Unterbrechungen gehören:
hidl_interface
-Module mitproduct_specific: true
sind für Systemmodule nicht verfügbar. Ersetzen Sieproduct_specific: true
durchsystem_ext_specific: true
, um das Problem zu beheben.- In den Modulen fehlt möglicherweise die für Produktmodule erforderliche Produktvariante. Um das Problem zu beheben, stellen Sie das Modul für die
product
-Partition zur Verfügung, indem Sieproduct_available: true
festlegen, oder verschieben Sie das Modul in dieproduct
-Partition, indem Sieproduct_specific: true
festlegen.
Beheben Sie Build-Fehler und prüfen Sie, ob das Gerät erfolgreich erstellt werden kann.
Flashen Sie das Image und suchen Sie im Boot-Vorgang und in den Protokollen des Geräts nach Laufzeitfehlern.
- Wenn im
linker
-Tag aus einem Testfallprotokoll eineCANNOT 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:
oderrequired:
hinzu.
- Wenn im
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. Achten Sie auf zwei bestimmte Arten von Fehlern:
Fehler beim Linktyp Dieser Fehler gibt an, dass eine App auf Java-Module verweist, die eine breitere
sdk_version
haben. Sie können das Problem beheben, indem 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, da es sich in einer verborgenen API befindet. Verwenden Sie eine sichtbare (nicht ausgeblendete) API oder suchen Sie nach einer 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 erwartungsgemäß ist. 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 Nutzung (Verknüpfung oder Reflexion), die Einschränkungsebene und den Aufrufstack 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 im Hilfeartikel Mit dem Veridex-Tool testen.
Schritt 6: device.mk aktualisieren
Nachdem Sie alle Build- und Laufzeitfehler behoben und geprüft haben, ob das Laufzeitverhalten den Erwartungen entspricht, legen Sie in device.mk
Folgendes fest:
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true