In Android 11 können Sie AIDL für HALs in Android verwenden. So können Teile von Android ohne HIDL implementiert werden. HALs nach Möglichkeit ausschließlich auf AIDL umstellen (wenn vorgelagerte HALs HIDL verwenden, muss HIDL verwendet werden).
HALs, die AIDL zur Kommunikation zwischen Framework-Komponenten wie denen in system.img
und Hardwarekomponenten wie denen in vendor.img
verwenden, müssen stabiles AIDL verwenden. Für die Kommunikation innerhalb einer Partition, z. B. von einem HAL zu einem anderen, gibt es jedoch keine Einschränkungen für den zu verwendenden IPC-Mechanismus.
Ziel
AIDL gibt es schon länger als HIDL und wird an vielen anderen Stellen verwendet, z. B. zwischen Android-Framework-Komponenten oder in Apps. Da AIDL jetzt Stabilität unterstützt, ist es möglich, einen gesamten Stack mit einer einzigen IPC-Laufzeit zu implementieren. AIDL hat außerdem ein besseres Versionsverwaltungssystem als HIDL. Hier sind einige Vorteile von AIDL:
- Wenn Sie nur eine IPC-Sprache verwenden, müssen Sie nur eine Sprache lernen, debuggen, optimieren und sichern.
- AIDL unterstützt die In-Place-Versionierung für die Eigentümer einer Schnittstelle:
- Inhaber können am Ende von Schnittstellen Methoden oder Felder zu Parcelable-Objekten hinzufügen. Das bedeutet, dass es einfacher ist, Code im Laufe der Jahre zu versionieren, und dass die Kosten im Laufe der Jahre geringer sind (Typen können vor Ort geändert werden und es sind keine zusätzlichen Bibliotheken für jede Benutzeroberflächenversion erforderlich).
- Erweiterungsschnittstellen können zur Laufzeit und nicht im Typsystem angehängt werden. Daher müssen Downstream-Erweiterungen nicht auf neuere Versionen von Schnittstellen umgestellt werden.
- Eine vorhandene AIDL-Schnittstelle kann direkt verwendet werden, wenn der Eigentümer sie stabilisiert. Bisher musste eine vollständige Kopie der Schnittstelle in HIDL erstellt werden.
Mit der AIDL-Laufzeit erstellen
AIDL hat drei verschiedene Backends: Java, NDK und CPP. Wenn Sie stabiles AIDL verwenden möchten, verwenden Sie immer die Systemkopie von libbinder
unter system/lib*/libbinder.so
und sprechen Sie über /dev/binder
. Für Code im vendor
-Image bedeutet das, dass libbinder
(aus dem VNDK) nicht verwendet werden kann: Diese Bibliothek hat eine instabile C++-API und instabile interne Funktionen. Stattdessen muss nativer Anbietercode das NDK-Backend von AIDL verwenden, mit libbinder_ndk
(das vom Systemlibbinder.so
unterstützt wird) verknüpft werden und mit den NDK-Bibliotheken verknüpft werden, die durch aidl_interface
-Einträge erstellt wurden. Die genauen Modulnamen finden Sie unter Regeln für die Benennung von Modulen.
AIDL HAL-Schnittstelle schreiben
Damit eine AIDL-Schnittstelle zwischen System und Anbieter verwendet werden kann, sind zwei Änderungen erforderlich:
- Jede Typdefinition muss mit
@VintfStability
annotiert sein. - Die
aidl_interface
-Erklärung mussstability: "vintf",
enthalten.
Nur der Inhaber einer Benutzeroberfläche kann diese Änderungen vornehmen.
Wenn Sie diese Änderungen vornehmen, muss sich die Benutzeroberfläche im VINTF-Manifest befinden, damit sie funktioniert. Testen Sie dies (und zugehörige Anforderungen, z. B. die Überprüfung, ob freigegebene Schnittstellen eingefroren sind) mit dem VTS-Test vts_treble_vintf_vendor_test
. Sie können eine @VintfStability
-Schnittstelle ohne diese Anforderungen verwenden, indem Sie entweder AIBinder_forceDowngradeToLocalStability
im NDK-Backend, android::Stability::forceDowngradeToLocalStability
im C++-Backend oder android.os.Binder#forceDowngradeToSystemStability
im Java-Backend auf ein Binder-Objekt aufrufen, bevor es an einen anderen Prozess gesendet wird.
Außerdem sollten Sie das CPP-Backend deaktivieren, um die Code-Übertragbarkeit zu maximieren und potenzielle Probleme wie unnötige zusätzliche Bibliotheken zu vermeiden.
Die Verwendung von backends
im folgenden Codebeispiel ist korrekt, da es drei Backends gibt (Java, NDK und CPP). Im Code wird gezeigt, wie ein CPP-Backend deaktiviert wird:
aidl_interface: {
...
backends: {
cpp: {
enabled: false,
},
},
}
AIDL HAL-Schnittstellen finden
Stabile AOSP-AIDL-Schnittstellen für HALs befinden sich in denselben Basisverzeichnissen wie HIDL-Schnittstellen in Ordnern mit der Endung aidl
:
hardware/interfaces
ist für Schnittstellen vorgesehen, die in der Regel von Hardware bereitgestellt werden.frameworks/hardware/interfaces
ist für Hochschulabsolventen vorgesehen, die für Hardware zuständig sind.system/hardware/interfaces
ist für Low-Level-Schnittstellen gedacht, die für die Hardware bereitgestellt werden.
Legen Sie Erweiterungsoberflächen in anderen hardware/interfaces
-Unterverzeichnissen in vendor
oder hardware
ab.
Erweiterungsschnittstellen
Android hat mit jeder Version eine Reihe offizieller AOSP-Schnittstellen. Wenn Android-Partner diesen Schnittstellen Funktionen hinzufügen möchten, sollten sie diese nicht direkt ändern, da ihre Android-Laufzeit dann nicht mehr mit der AOSP-Android-Laufzeit kompatibel ist. Ändern Sie diese Schnittstellen nicht, damit das GSI-Image weiterhin funktioniert.
Erweiterungen können auf zwei verschiedene Arten registriert werden:
- Zur Laufzeit; siehe Angehängte Erweiterungsoberflächen
- Als eigenständiges, weltweit und in VINTF registriertes Unternehmen
Wenn eine Erweiterung registriert ist und die Schnittstelle von anbieterspezifischen Komponenten (d. h. nicht Teil des Upstream-AOSP) verwendet wird, sind Zusammenführungskonflikte nicht möglich. Wenn jedoch Downstream-Änderungen an Upstream-AOSP-Komponenten vorgenommen werden, können Zusammenführungskonflikte auftreten. In diesem Fall werden die folgenden Strategien empfohlen:
- Reichen Sie die Interface-Erweiterungen im nächsten Release an AOSP weiter.
- Ergänzungen der Upstream-Benutzeroberfläche, die in der nächsten Version mehr Flexibilität (ohne Zusammenführungskonflikte) ermöglichen.
Parcelable-Objekte für Erweiterungen: ParcelableHolder
ParcelableHolder
ist eine Instanz der Parcelable
-Benutzeroberfläche, die eine weitere Instanz von Parcelable
enthalten kann.
Der Hauptanwendungsfall von ParcelableHolder
besteht darin, Parcelable
erweiterbar zu machen.
Angenommen, Geräteimplementierer erwarten, dass sie eine von AOSP definierte Parcelable
, AospDefinedParcelable
, um ihre Mehrwertfunktionen erweitern können.
Mit der ParcelableHolder
-Benutzeroberfläche kannst du Parcelable
um deine Mehrwertfunktionen erweitern. Die Schnittstelle ParcelableHolder
enthält eine Instanz von Parcelable
. Wenn Sie versuchen, Parcelable
direkt Felder hinzuzufügen, tritt ein Fehler auf:
parcelable AospDefinedParcelable {
int a;
String b;
String x; // ERROR: added by a device implementer
int[] y; // added by a device implementer
}
Wie im vorherigen Code zu sehen, ist diese Vorgehensweise nicht zulässig, da die vom Geräteimplementierer hinzugefügten Felder in Konflikt stehen können, wenn Parcelable
in den nächsten Android-Releases überarbeitet wird.
Mit ParcelableHolder
kann der Inhaber eines Parcelable-Objekts einen Erweiterungspunkt in einer Instanz von Parcelable
definieren:
parcelable AospDefinedParcelable {
int a;
String b;
ParcelableHolder extension;
}
Anschließend können die Geräteimplementierer eine eigene Parcelable
-Instanz für ihre Erweiterung definieren:
parcelable OemDefinedParcelable {
String x;
int[] y;
}
Die neue Parcelable
-Instanz kann über das Feld ParcelableHolder
an die ursprüngliche Parcelable
angehängt werden:
// Java
AospDefinedParcelable ap = ...;
OemDefinedParcelable op = new OemDefinedParcelable();
op.x = ...;
op.y = ...;
ap.extension.setParcelable(op);
...
OemDefinedParcelable op = ap.extension.getParcelable(OemDefinedParcelable.class);
// C++
AospDefinedParcelable ap;
OemDefinedParcelable op;
std::shared_ptr<OemDefinedParcelable> op_ptr = make_shared<OemDefinedParcelable>();
ap.extension.setParcelable(op);
ap.extension.setParcelable(op_ptr);
...
std::shared_ptr<OemDefinedParcelable> op_ptr;
ap.extension.getParcelable(&op_ptr);
// NDK
AospDefinedParcelable ap;
OemDefinedParcelable op;
ap.extension.setParcelable(op);
...
std::optional<OemDefinedParcelable> op;
ap.extension.getParcelable(&op);
// Rust
let mut ap = AospDefinedParcelable { .. };
let op = Rc::new(OemDefinedParcelable { .. });
ap.extension.set_parcelable(Rc::clone(&op));
...
let op = ap.extension.get_parcelable::<OemDefinedParcelable>();
Namen der AIDL HAL-Serverinstanz
AIDL HAL-Dienste haben üblicherweise einen Instanznamen im Format $package.$type/$instance
. Beispielsweise wird eine Instanz der HAL für den Vibrator als android.hardware.vibrator.IVibrator/default
registriert.
AIDL HAL-Server schreiben
@VintfStability
AIDL-Server müssen im VINTF-Manifest deklariert werden, z. B.:
<hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1</version>
<fqname>IVibrator/default</fqname>
</hal>
Andernfalls sollte er einen AIDL-Dienst wie gewohnt registrieren. Bei der Ausführung von VTS-Tests sollten alle deklarierten AIDL HALs verfügbar sein.
AIDL-Client schreiben
AIDL-Clients müssen sich in der Kompatibilitätsmatrix deklarieren, z. B. so:
<hal format="aidl" optional="true">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
</interface>
</hal>
Vorhandene HAL von HIDL in AIDL konvertieren
Verwenden Sie das hidl2aidl
-Tool, um eine HIDL-Schnittstelle in AIDL zu konvertieren.
hidl2aidl
-Funktionen:
- Erstellen Sie AIDL-Dateien (
.aidl
) basierend auf den HAL-Dateien (.hal
) für das jeweilige Paket. - Erstellen Sie Build-Regeln für das neu erstellte AIDL-Paket mit allen aktivierten Back-Ends.
- Erstellen Sie Übersetzungsmethoden in den Java-, CPP- und NDK-Back-Ends, um von den HIDL-Typen zu den AIDL-Typen zu übersetzen.
- Erstellen Sie Build-Regeln für Übersetzungsbibliotheken mit den erforderlichen Abhängigkeiten.
- Erstellen Sie statische Assertions, um sicherzustellen, dass HIDL- und AIDL-Enumeratoren in den CPP- und NDK-Backends dieselben Werte haben.
So konvertieren Sie ein Paket mit HAL-Dateien in AIDL-Dateien:
Erstellen Sie das Tool unter
system/tools/hidl/hidl2aidl
.Wenn Sie dieses Tool aus der neuesten Quelle erstellen, erhalten Sie die beste Leistung. Mit der neuesten Version können Sie Benutzeroberflächen in älteren Release-Branches konvertieren:
m hidl2aidl
Führen Sie das Tool mit einem Ausgabeverzeichnis gefolgt vom zu konvertierenden Paket aus.
Optional kannst du mit dem Argument
-l
den Inhalt einer neuen Lizenzdatei an den Anfang aller generierten Dateien einfügen. Achten Sie darauf, die richtige Lizenz und das richtige Datum zu verwenden:hidl2aidl -o <output directory> -l <file with license> <package>
Beispiel:
hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
Sehen Sie sich die generierten Dateien an und beheben Sie alle Probleme mit der Umwandlung:
conversion.log
enthält alle nicht behobenen Probleme, die zuerst behoben werden müssen.- Die generierten AIDL-Dateien enthalten möglicherweise Warnungen und Vorschläge, die Sie beachten sollten. Diese Kommentare beginnen mit
//
. - Bereinigen und verbessern Sie das Paket.
- Prüfe die Anmerkung
@JavaDerive
auf Funktionen, die möglicherweise erforderlich sind, z. B.toString
oderequals
.
Erstellen Sie nur die Ziele, die Sie benötigen:
- Deaktivieren Sie Backends, die nicht verwendet werden. Verwenden Sie das NDK-Back-End anstelle des CPP-Back-Ends. Weitere Informationen finden Sie unter Mit der AIDL-Laufzeit erstellen.
- Entfernen Sie Übersetzungsbibliotheken oder den generierten Code, der nicht verwendet wird.
Weitere Informationen finden Sie unter Wichtige Unterschiede zwischen AIDL und HIDL:
- Die Verwendung der integrierten
Status
- und Ausnahmetypen von AIDL verbessert in der Regel die Benutzeroberfläche und macht einen weiteren schnittstellenspezifischen Statustyp überflüssig. - AIDL-Schnittstellenargumente in Methoden sind standardmäßig nicht
@nullable
, wie es in HIDL der Fall war.
- Die Verwendung der integrierten
SEPolicy für AIDL HALs
Ein AIDL-Diensttyp, der für Anbietercode sichtbar ist, muss das Attribut hal_service_type
haben. Ansonsten entspricht die Sepolicy-Konfiguration der eines anderen AIDL-Dienstes (es gibt jedoch spezielle Attribute für HALs). Hier ist eine Beispieldefinition für einen HAL-Dienstkontext:
type hal_foo_service, service_manager_type, hal_service_type;
Für die meisten von der Plattform definierten Dienste ist bereits ein Dienstkontext mit dem richtigen Typ hinzugefügt. android.hardware.foo.IFoo/default
ist beispielsweise bereits als hal_foo_service
gekennzeichnet. Wenn ein Framework-Client jedoch mehrere Instanznamen unterstützt, müssen in gerätespezifischen service_contexts
-Dateien zusätzliche Instanznamen hinzugefügt werden:
android.hardware.foo.IFoo/custom_instance u:object_r:hal_foo_service:s0
Wenn Sie einen neuen HAL-Typ erstellen, müssen Sie HAL-Attribute hinzufügen. Ein bestimmtes HAL-Attribut kann mehreren Diensttypen zugeordnet sein, von denen jeder wie bereits erwähnt mehrere Instanzen haben kann. Für eine HAL, foo
, gibt es hal_attribute(foo)
. Dieses Makro definiert die Attribute hal_foo_client
und hal_foo_server
. Mit den Makros hal_client_domain
und hal_server_domain
wird einer Domain ein bestimmtes HAL-Attribut zugewiesen. Wenn der Systemserver beispielsweise ein Client dieser HAL ist, entspricht das der Richtlinie hal_client_domain(system_server, hal_foo)
. Ein HAL-Server enthält ebenfalls hal_server_domain(my_hal_domain, hal_foo)
.
Für ein bestimmtes HAL-Attribut wird in der Regel auch eine Domain wie hal_foo_default
für Referenz- oder Beispiel-HALs erstellt. Einige Geräte verwenden diese Domains jedoch für ihre eigenen Server. Eine Unterscheidung zwischen Domains für mehrere Server ist nur dann wichtig, wenn es mehrere Server gibt, die dieselbe Benutzeroberfläche bereitstellen und in ihren Implementierungen unterschiedliche Berechtigungssätze benötigen.
In allen diesen Makros ist hal_foo
kein SEPolicy-Objekt. Stattdessen wird dieses Token von diesen Makros verwendet, um auf die Gruppe von Attributen zu verweisen, die mit einem Client-Server-Paar verknüpft sind.
Bisher sind hal_foo_service
und hal_foo
(das Attributpaar aus hal_attribute(foo)
) jedoch nicht verknüpft. Ein HAL-Attribut wird mit AIDL HAL-Diensten über das hal_attribute_service
-Makro verknüpft (HIDL HALs verwenden das hal_attribute_hwservice
-Makro), z. B. hal_attribute_service(hal_foo, hal_foo_service)
. Das bedeutet, dass hal_foo_client
-Prozesse auf die HAL zugreifen und hal_foo_server
-Prozesse die HAL registrieren können. Die Durchsetzung dieser Registrierungsregeln erfolgt durch den Context Manager (servicemanager
).
Dienstnamen stimmen möglicherweise nicht immer mit HAL-Attributen überein, z. B. hal_attribute_service(hal_foo, hal_foo2_service)
. Da dies impliziert, dass die Dienste immer zusammen verwendet werden, können Sie im Allgemeinen hal_foo2_service
entfernen und hal_foo_service
für alle Dienstkontexte verwenden. Wenn HALs mehrere hal_attribute_service
-Instanzen festlegen, liegt das daran, dass der ursprüngliche HAL-Attributname nicht allgemein genug ist und nicht geändert werden kann.
Zusammengenommen sieht eine Beispiel-HAL so aus:
public/attributes:
// define hal_foo, hal_foo_client, hal_foo_server
hal_attribute(foo)
public/service.te
// define hal_foo_service
type hal_foo_service, hal_service_type, protected_service, service_manager_type
public/hal_foo.te:
// allow binder connection from client to server
binder_call(hal_foo_client, hal_foo_server)
// allow client to find the service, allow server to register the service
hal_attribute_service(hal_foo, hal_foo_service)
// allow binder communication from server to service_manager
binder_use(hal_foo_server)
private/service_contexts:
// bind an AIDL service name to the selinux type
android.hardware.foo.IFooXxxx/default u:object_r:hal_foo_service:s0
private/<some_domain>.te:
// let this domain use the hal service
binder_use(some_domain)
hal_client_domain(some_domain, hal_foo)
vendor/<some_hal_server_domain>.te
// let this domain serve the hal service
hal_server_domain(some_hal_server_domain, hal_foo)
Angehängte Erweiterungsschnittstellen
Eine Erweiterung kann an jede Binder-Oberfläche angehängt werden, unabhängig davon, ob es sich um eine direkt beim Dienstmanager registrierte Oberfläche der obersten Ebene oder um eine untergeordnete Oberfläche handelt. Wenn Sie eine Verlängerung erhalten, müssen Sie bestätigen, dass der Typ der Verlängerung wie erwartet ist. Sie können Erweiterungen nur über den Prozess festlegen, der einen Binder bereitstellt.
Verwenden Sie angehängte Erweiterungen, wenn eine Erweiterung die Funktionalität einer vorhandenen HAL ändert. Wenn eine völlig neue Funktion erforderlich ist, ist dieser Mechanismus nicht erforderlich. Sie können eine Erweiterungsoberfläche direkt beim Dienstmanager registrieren. Angehängte Erweiterungsschnittstellen sind am sinnvollsten, wenn sie an untergeordnete Schnittstellen angehängt sind, da diese Hierarchien tief oder mehrstufig sein können. Wenn Sie eine globale Erweiterung verwenden, um die Binder-Schnittstellenhierarchie eines anderen Dienstes zu spiegeln, ist umfangreiches Verwaltungsaufwand erforderlich, um direkt angehängten Erweiterungen vergleichbare Funktionen zur Verfügung zu stellen.
Verwenden Sie die folgenden APIs, um eine Erweiterung für einen Binder festzulegen:
- NDK-Backend:
AIBinder_setExtension
- Java-Backend:
android.os.Binder.setExtension
- CPP-Backend:
android::Binder::setExtension
- Rust-Backend:
binder::Binder::set_extension
Verwenden Sie die folgenden APIs, um eine Verlängerung für einen Ausweis zu erhalten:
- NDK-Backend:
AIBinder_getExtension
- Java-Backend:
android.os.IBinder.getExtension
- CPP-Backend:
android::IBinder::getExtension
- Rust-Backend:
binder::Binder::get_extension
Weitere Informationen zu diesen APIs finden Sie in der Dokumentation der getExtension
-Funktion im entsprechenden Backend. Ein Beispiel für die Verwendung von Erweiterungen finden Sie unter hardware/interfaces/tests/extension/vibrator
.
Wichtige Unterschiede zwischen AIDL und HIDL
Wenn Sie AIDL HALs oder AIDL HAL-Schnittstellen verwenden, beachten Sie die Unterschiede zum Schreiben von HIDL HALs.
- Die Syntax der AIDL-Sprache ähnelt eher Java. Die HIDL-Syntax ähnelt C++.
- Alle AIDL-Schnittstellen haben integrierte Fehlerstatus. Anstatt benutzerdefinierte Statustypen zu erstellen, erstellen Sie in den Schnittstellendateien Konstante Status-Ints und verwenden Sie
EX_SERVICE_SPECIFIC
in den CPP- und NDK-Back-Ends undServiceSpecificException
im Java-Back-End. Weitere Informationen finden Sie unter Fehlerbehandlung. - AIDL startet keine Threadpools automatisch, wenn Binderobjekte gesendet werden. Sie müssen sie manuell starten (siehe Unterhaltungsverwaltung).
- AIDL beendet die Übertragung nicht bei nicht geprüften Transportfehlern (HIDL
Return
beendet die Übertragung bei nicht geprüften Fehlern). - In AIDL kann nur ein Typ pro Datei deklariert werden.
- AIDL-Argumente können zusätzlich zum Ausgabeparameter als
in
,out
oderinout
angegeben werden. Es gibt keine synchronen Rückrufe. - In AIDL wird
fd
anstelle vonhandle
als primitiver Typ verwendet. - HIDL verwendet Hauptversionen für inkompatible Änderungen und Nebenversionen für kompatible Änderungen. In AIDL werden abwärtskompatible Änderungen direkt vorgenommen.
AIDL hat kein explizites Konzept für Hauptversionen. Stattdessen wird dies in Paketnamen einbezogen. AIDL kann beispielsweise den Paketnamen
bluetooth2
verwenden. - AIDL erbt standardmäßig keine Echtzeitpriorität. Die Funktion
setInheritRt
muss pro Binder verwendet werden, um die Echtzeitprioritätsübernahme zu aktivieren.
Vendor Test Suite (VTS)-Tests für HALs
Android nutzt die Vendor Test Suite (VTS), um die erwarteten HAL-Implementierungen zu überprüfen. VTS trägt dazu bei, dass Android abwärtskompatibel mit alten Anbieterimplementierungen ist. Bei Implementierungen, die den VTS-Test nicht bestehen, sind bekannte Kompatibilitätsprobleme bekannt, die die Funktion mit zukünftigen Versionen des Betriebssystems beeinträchtigen können.
VTS für HALs besteht aus zwei Hauptteilen.
1. Prüfen, ob die HALs auf dem Gerät von Android bekannt und erwartet werden
Diese Tests finden Sie unter test/vts-testcase/hal/treble/vintf
.
Bei diesen Tests wird Folgendes überprüft:
- Jede
@VintfStability
-Schnittstelle, die in einem VINTF-Manifest deklariert ist, wird auf einer bekannten veröffentlichten Version eingefroren. So wird sichergestellt, dass sich beide Seiten der Schnittstelle über die genaue Definition dieser Version der Schnittstelle einigen. Dies ist für die grundlegende Funktion erforderlich. - Alle HALs, die in einem VINTF-Manifest deklariert sind, sind auf diesem Gerät verfügbar. Jeder Client mit ausreichenden Berechtigungen zur Verwendung eines deklarierten HAL-Dienstes muss diese Dienste jederzeit abrufen und verwenden können.
- Alle HALs, die in einem VINTF-Manifest deklariert sind, dienen der Version der Benutzeroberfläche, die im Manifest deklariert ist.
- Auf einem Gerät werden keine veralteten HALs bereitgestellt. Android unterstützt keine niedrigeren Versionen von HAL-Schnittstellen mehr, wie im FCM-Lebenszyklus beschrieben.
- Auf dem Gerät sind die erforderlichen HALs vorhanden. Einige HALs sind erforderlich, damit Android ordnungsgemäß funktioniert.
2. Erwartetes Verhalten der einzelnen HALs prüfen
Für jede HAL-Schnittstelle gibt es eigene VTS-Tests, um das erwartete Verhalten der Clients zu überprüfen. Die Testfälle werden auf jeder Instanz einer deklarierten HAL-Schnittstelle ausgeführt und erzwingen ein bestimmtes Verhalten basierend auf der implementierten Version der Schnittstelle.
Bei diesen Tests wird versucht, jeden Aspekt der HAL-Implementierung abzudecken, auf den das Android-Framework angewiesen ist oder in Zukunft angewiesen sein könnte.
Dazu gehören die Überprüfung der Unterstützung von Funktionen, der Fehlerbehandlung und aller anderen Verhaltensweisen, die ein Kunde vom Dienst erwarten kann.
VTS-Meilensteine für die HAL-Entwicklung
VTS-Tests müssen aktualisiert werden, wenn die HAL-Schnittstellen von Android erstellt oder geändert werden.
VTS-Tests müssen abgeschlossen sein und die Anbieterimplementierungen müssen bereit sein, um überprüft zu werden, bevor sie für Android-Anbieter API-Releases eingefroren werden. Sie müssen fertig sein, bevor die Schnittstellen eingefroren werden, damit die Entwickler ihre Implementierungen erstellen, überprüfen und Feedback an die Entwickler der HAL-Schnittstelle geben können.
VTS auf Cuttlefish
Wenn keine Hardware verfügbar ist, verwendet Android Cuttlefish als Entwicklungstool für HAL-Schnittstellen. Dies ermöglicht skalierbare VTS- und Integrationstests von Android.
Mit hal_implementation_test
wird geprüft, ob Cuttlefish Implementierungen der neuesten HAL-Schnittstellenversionen hat, damit Android die neuen Schnittstellen verarbeiten kann. Außerdem werden die VTS-Tests so vorbereitet, dass sie die neuen Implementierungen der Anbieter testen können, sobald neue Hardware und Geräte verfügbar sind.