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 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)
Bei der Erzwingung sind keine anderen Verknüpfungen mit Partitionen als der product
-Partition zulässig.
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
-Properties zusammengefasst, mit denen Bildvarianten erstellt werden.
Properties in Android.bp | Erstellte Varianten | |
---|---|---|
Vor der Durchsetzung | Nach der Durchsetzung | |
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 |
core, vendor | core, vendor |
product_available: true |
– | core, product |
vendor_available: true UND product_available:
true |
– | core, product, vendor |
system_ext_specific: true UND vendor_available:
true |
core, vendor | core, vendor |
product_specific: true UND vendor_available:
true |
core, vendor | Produkt, Anbieter |
Erzwingung zur Buildzeit (Android.mk)
Wenn die Erzwingung der nativen Benutzeroberfläche aktiviert ist, haben native Module, die in der product
-Partition installiert sind, einen native:product
-Linktyp, 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 gilt auch für die Verknüpfung während des Builds 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
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.
Laufzeitdurchsetzung
Die Android-Laufzeit prüft, ob Apps in der Partition product
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 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 ermitteln (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 | Laufzeitverhalten prüfen | 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.
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),)
Erben Sie in der Datei
device.mk
das gemeinsame Makefile für die Partitionsystem
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, bei dem PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
auf strict
festgelegt ist, können Makefiles außerhalb von oem_system.mk
keine Module enthalten, die in der Partition root
oder system
installiert sind. 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 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: Zulassungsliste 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. 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 Protokolle und finden und beheben Laufzeitverknüpfungsfehler:
Legen Sie
PRODUCT_PRODUCT_VNDK_VERSION := current
fest.Erstellen Sie das Gerät und prüfen Sie, ob Build-Fehler auftreten. Wahrscheinlich treten einige Buildunterbrechungen aufgrund fehlender Produkt- oder Hauptvarianten auf. 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 Buildfehler und sorgen Sie dafür, dass das Gerät erfolgreich erstellt wird.
Flashen Sie das Image und suchen Sie im Bootvorgang 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 genannten Anleitung.
Schritt 4: Java-Schnittstellen erzwingen
In diesem Schritt legen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
fest und suchen dann nach den resultierenden Build-Fehlern, 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 gibt an, dass ein Symbol nicht gefunden werden kann, weil es sich in einer ausgeblendeten 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 den Erwartungen entspricht. Bei Apps, die debugfähig sind, können Sie die Nutzung versteckter APIs mithilfe von StrictMode.detectNonSdkApiUsage
überwachen. Dadurch wird ein Protokoll 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 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 ü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