Android 11 entbündelt die product
und macht sie unabhängig von den system
und vendor
. Im Rahmen dieser Änderungen können Sie jetzt den Zugriff der product
auf native und Java-Schnittstellen steuern (ähnlich wie die Schnittstellendurchsetzung für vendor
funktioniert).
Durchsetzung nativer Schnittstellen
Um die Durchsetzung der nativen Schnittstelle zu aktivieren, setzen Sie PRODUCT_PRODUCT_VNDK_VERSION
auf current
. (Die Version wird automatisch auf current
gesetzt, wenn die Versand-API-Ebene für das Ziel größer als 29 ist.) Durch die Durchsetzung ist Folgendes möglich:
- Native Module in der
product
zum Verknüpfen:- Statisch oder dynamisch zu anderen Modulen in der
product
, die statische, gemeinsam genutzte oder Header-Bibliotheken enthalten. - Dynamisch zu VNDK-Bibliotheken in der
system
.
- Statisch oder dynamisch zu anderen Modulen in der
- JNI-Bibliotheken in entbündelten APKs in der
product
zur Verknüpfung mit Bibliotheken in/product/lib
oder/product/lib64
(dies gilt zusätzlich zu den NDK-Bibliotheken).
Die Durchsetzung lässt keine anderen Links zu anderen Partitionen als der product
zu.
Durchsetzung der Build-Zeit (Android.bp)
In Android 11 können Systemmodule zusätzlich zu Kern- und Anbieter-Image-Varianten auch eine Produkt-Image-Variante erstellen. Wenn die Durchsetzung der nativen Schnittstelle aktiviert ist ( PRODUCT_PRODUCT_VNDK_VERSION
ist auf current
gesetzt):
Native Module in der
product
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 auf andere Bibliotheken verweisen, dieproduct_specific: true
oderproduct_available: true
in ihrenAndroid.bp
Dateien angeben.VNDK-Bibliotheken müssen
product_available: true
in ihrenAndroid.bp
Dateien haben, damitproduct
mit VNDK-Bibliotheken verknüpft werden können.
Die folgende Tabelle fasst die Android.bp
Eigenschaften zusammen, die zum Erstellen von Bildvarianten verwendet werden.
Eigenschaften in Android.bp | Varianten erstellt | |
---|---|---|
Vor der Durchsetzung | Nach der Durchsetzung | |
Standard (keine) | Kern (einschließlich | Kern (Enthält |
system_ext_specific: true | Kern | Kern |
product_specific: true | Kern | Produkt |
vendor: true | Verkäufer | Verkäufer |
vendor_available: true | Kern, Anbieter | Kern, Anbieter |
product_available: true | N / A | Kernprodukt |
vendor_available: true UND product_available: true | N / A | 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 |
Durchsetzung der Build-Zeit (Android.mk)
Wenn die Erzwingung der nativen Schnittstelle aktiviert ist, verfügen die auf der product
installierten nativen Module über einen native:product
Linktyp, der nur mit anderen native:product
oder native:vndk
Modulen verknüpft werden kann. Der Versuch, eine Verbindung zu anderen Modulen als diesen herzustellen, führt dazu, dass das Build-System einen Fehler bei der Überprüfung des Verbindungstyps generiert.
Laufzeitdurchsetzung
Wenn die Durchsetzung der nativen Schnittstelle aktiviert ist, erlaubt die Linkerkonfiguration für den bionischen Linker nicht, dass Systemprozesse product
verwenden, wodurch ein product
für die product
erstellt wird, die keine Verknüpfung zu Bibliotheken außerhalb der product
erstellen können (solche Prozesse können dies jedoch). Link zu VNDK-Bibliotheken). Versuche, die Laufzeit-Link-Konfiguration zu verletzen, führen dazu, dass der Prozess fehlschlägt und die Fehlermeldung CANNOT LINK EXECUTABLE
generiert wird.
Durchsetzung von Java-Schnittstellen
Um die Durchsetzung der Java-Schnittstelle zu aktivieren, 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 größer als 29 ist.) Wenn aktiviert, erlaubt/verbietet die Durchsetzung den folgenden Zugriff.
API | /System | /system_ext | /Produkt | /Verkäufer | /Daten |
---|---|---|---|---|---|
Öffentliche API | |||||
@SystemApi | |||||
@hide-API |
Wie in der vendor
darf eine App oder eine Java-Bibliothek in der product
nur öffentliche und System-APIs verwenden; Das Verknüpfen mit einer Bibliothek, die versteckte APIs verwendet, ist nicht zulässig. Diese Einschränkung umfasst die Verknüpfung zur Erstellungszeit und die Reflexion zur Laufzeit.
Durchsetzung der Bauzeit
Zur Erstellungszeit stellen Make und Soong sicher, dass Java-Module in der product
keine versteckten APIs verwenden, indem sie die Felder platform_apis
“ und sdk_version
überprüfen. Die sdk_version
der Apps in der product
muss mit current
, system_current
oder numerischen Version der API gefüllt sein und das Feld platform_apis
muss leer sein.
Durchsetzung der Laufzeit
Die Android-Laufzeit überprüft, ob Apps in der product
keine versteckten APIs, einschließlich Reflektion, verwenden. Einzelheiten finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen .
Durchsetzung 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, das die Pakete für die system angibt, und legen Sie dann die Artefaktpfad-Anforderungsprüfung in der device.mk fest (um zu verhindern, dass Nicht-Systemmodule auf der system installiert werden). | N |
2 | Bereinigen Sie die Zulassungsliste. | N |
3 | Erzwingen Sie native Schnittstellen und identifizieren Sie Laufzeitverbindungsfehler (kann parallel zur Java-Erzwingung ausgeführt werden). | Y |
4 | Erzwingen Sie Java-Schnittstellen und überprüfen Sie das Laufzeitverhalten (kann parallel zur nativen Durchsetzung ausgeführt werden). | Y |
5 | Überprüfen Sie das Laufzeitverhalten. | Y |
6 | Aktualisieren Sie device.mk mit der Durchsetzung der Produktschnittstelle. | Y |
Schritt 1: Makefile erstellen und Artefaktpfadprüfung aktivieren
In diesem Schritt definieren Sie das system
-Makefile.
Erstellen Sie ein Makefile, das die Pakete für die
system
definiert. Erstellen Sie beispielsweise eineoem_system.mk
Datei mit Folgendem:$(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 diesystem
und aktivieren Sie die Überprüfung der Artefaktpfadanforderungen. Zum Beispiel:$(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk) # Enable artifact path requirements checking PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
Informationen zu den Anforderungen an den Artefaktpfad
Wenn PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
auf true
oder strict
gesetzt ist, verhindert das Build-System, dass in anderen Makefiles definierte Pakete auf den in require-artifacts-in-path
definierten Pfaden installiert werden , und verhindert, dass im aktuellen Makefile definierte Pakete Artefakte außerhalb der in require-artifacts-in-path
-artifacts-in-path definierten Pfade installieren. require-artifacts-in-path
.
Im obigen Beispiel können Makefiles außerhalb oem_system.mk
, wenn PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS
auf strict
gesetzt ist, keine Module enthalten, die auf der root
oder system
installiert sind. Um diese Module einzubinden, müssen Sie sie entweder in der Datei oem_system.mk
selbst oder in einem enthaltenen Makefile definieren. Versuche, Module auf unzulässigen Pfaden zu installieren, führen zu Build-Unterbrechungen. Um Unterbrechungen zu beheben, führen Sie einen der folgenden Schritte aus:
Option 1: Binden Sie das Systemmodul in die Makefiles ein, die in
oem_system.mk
enthalten sind. Dadurch wird die Anforderung an den Artefaktpfad erfüllt (da die Module jetzt in einem enthaltenen Makefile vorhanden sind) und somit die Installation in den Pfaden in „require-artifacts-in-path“ ermöglicht.Option 2: Module auf der
system_ext
oderproduct
installieren (und keine Module auf dersystem
installieren).Option 3: Module zur
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
hinzufügen. Hier werden die zulässigen Module aufgeführt, die installiert werden dürfen.
Schritt 2: Leeren Sie die Zulassungsliste
In diesem Schritt machen Sie PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
leer, sodass alle Geräte, die oem_system.mk
gemeinsam nutzen, auch ein einzelnes system
gemeinsam nutzen können. Um die Liste der zulässigen Module zu leeren, verschieben Sie alle Module in der Liste in die system_ext
oder product
oder fügen Sie sie den system
Make-Dateien hinzu. Dieser Schritt ist optional, da die Definition eines gemeinsamen system
nicht erforderlich ist, um die Durchsetzung der Produktschnittstelle zu ermöglichen. Das Leeren der erlaubten Liste ist jedoch hilfreich, um die system
mit system_ext
zu definieren.
Schritt 3: Erzwingen Sie native Schnittstellen
In diesem Schritt legen Sie PRODUCT_PRODUCT_VNDK_VERSION := current
fest, suchen dann nach Build- und Laufzeitfehlern und beheben diese. So überprüfen Sie den Gerätestart und die Protokolle und finden und beheben Fehler bei der Laufzeitverknüpfung:
Legen Sie
PRODUCT_PRODUCT_VNDK_VERSION := current
fest.Bauen Sie das Gerät und suchen Sie nach Baufehlern. Es wird wahrscheinlich zu einigen Build-Unterbrechungen aufgrund fehlender Produktvarianten oder Kernvarianten kommen. Zu den häufigsten Pausen gehören:
- Jedes
hidl_interface
Modul mitproduct_specific: true
ist für Systemmodule nicht verfügbar. Um das Problem zu beheben, ersetzen Sieproduct_specific: true
durchsystem_ext_specfic: true
. - Den Modulen fehlt möglicherweise die für Produktmodule erforderliche Produktvariante. Um das Problem zu beheben, machen Sie das Modul für die
product
verfügbar, indem Sieproduct_available: true
festlegen, oder verschieben Sie das Modul in dieproduct
, indem Sieproduct_specific: true
festlegen.
- Jedes
Beheben Sie Buildfehler und stellen Sie sicher, dass das Gerät erfolgreich erstellt wird.
Flashen Sie das Image und suchen Sie nach Laufzeitfehlern im Gerätestart und in den Protokollen.
- Wenn das
linker
Tag aus einem Testfallprotokoll die MeldungCANNOT LINK EXECUTABLE
anzeigt, fehlt in der Make-Datei eine Abhängigkeit (und sie wurde zur Erstellungszeit nicht erfasst). - Um es vom Build-System aus zu überprüfen, fügen Sie die erforderliche Bibliothek zum Feld
shared_libs:
oderrequired:
hinzu.
- Wenn das
Beheben Sie die fehlenden Abhängigkeiten mithilfe der oben angegebenen Anleitung.
Schritt 4: Java-Schnittstellen erzwingen
In diesem Schritt legen Sie PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
fest und suchen und beheben dann resultierende Buildfehler. Suchen Sie nach zwei spezifischen Arten von Fehlern:
Fehler beim Linktyp. Dieser Fehler weist darauf hin, dass eine App auf Java-Module verweist, die über eine umfassendere
sdk_version
verfügen. Um das Problem zu beheben, können Sie diesdk_version
der App erweitern oder diesdk_version
der Bibliothek einschränken. 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 weist darauf hin, dass ein Symbol nicht gefunden werden kann, weil es sich in einer versteckten API befindet. Um das Problem zu beheben, verwenden Sie eine sichtbare (nicht ausgeblendete) API oder suchen Sie nach einer 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 überprüfen Sie, ob das Laufzeitverhalten den Erwartungen entspricht. Bei Apps, die debuggbar sind, können Sie die Nutzung versteckter APIs mithilfe eines Protokolls StrictMode.detectNonSdkApiUsage
überwachen (wodurch ein Protokoll generiert wird, wenn die App eine versteckte API verwendet). Alternativ können Sie das statische Analysetool von Veridex verwenden, um die Art der Nutzung (Verknüpfung oder Reflektion), 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;
Einzelheiten zur Verwendung von Veridex finden Sie unter Testen mit dem Veridex-Tool .
Schritt 6: Aktualisieren Sie device.mk
Nachdem Sie alle Build- und Laufzeitfehler behoben und überprüft haben, ob das Laufzeitverhalten den Erwartungen entspricht, legen Sie Folgendes in device.mk
fest:
-
PRODUCT_PRODUCT_VNDK_VERSION := current
-
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true