Die AIDL-VHAL ist in android.hardware.automotive.vehicle namespace
definiert.
Die VHAL-Schnittstelle ist unter IVehicle.aidl
definiert.
Sofern nicht anders angegeben, müssen alle Methoden für eine bestimmte VHAL-Version implementiert werden.
Versionen
Android-Version | Aktuelle VHAL-Version | Aktuelle VHAL-Property-Version | Mindestversion von VHAL |
---|---|---|---|
Android 16 | V4 | V4 | V1 |
Android 15 | V3 | V3 | V1 |
Android 14 | V2 | V2 | V1 |
Android 13 | V1 | (VHAL-Attributschnittstelle nicht aufgeteilt) | V1 |
Es wird EMPFOHLEN, die neueste VHAL-Version für eine bestimmte Android-Version zu implementieren.
Funktionen und Callbacks
Die VHAL-Funktionen sind unter IVehicle.aidl
definiert.
Methode | |
---|---|
VehiclePropConfigs getAllPropConfigs()
|
|
VehiclePropConfigs getPropConfigs(in int[] props)
|
|
void getValues(IVehicleCallback callback, in GetValueRequests requests)
GetValueRequest asynchron. Das Ergebnis wird über die onGetValues -Methode des Callbacks zurückgegeben. |
|
void setValues(IVehicleCallback callback, in SetValueRequests requests)
SetValueRequest asynchron. Das Ergebnis wird über die onSetValues -Methode des Callbacks zurückgegeben. |
|
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
maxSharedMemoryFileCount wird nicht verwendet. |
|
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
|
|
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
|
|
(Neu in Android 16)SupportedValuesListResults getSupportedValuesLists(in List
|
|
(Neu in Android 16)MinMaxSupportedValueResults getMinMaxSupportedValue(in List
|
|
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
|
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
Die Callbacks sind unter IVehicleCallback.aidl
definiert und enthalten diese Methoden.
Methode | |
---|---|
oneway void onGetValues(in GetValueResults responses)
getValues , um Ergebnisse für „get value“ zu liefern. Wird aufgerufen, wenn einige der abzurufenden Werte bereit sind. |
|
oneway void onSetValues(in SetValueResults responses)
setValues , um Ergebnisse für den festgelegten Wert zu liefern. Wird aufgerufen, wenn VHAL die Verarbeitung einiger Anfragen zum Festlegen von Attributen abgeschlossen hat. |
|
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
CONTINUOUS -Property tritt ein Property-Ereignis basierend auf der Abonnement-Abtastrate in Hz oder der Häufigkeit von Fahrzeugbusnachrichten auf. Ein Property-Ereignis kann auch auftreten, wenn sich der Status einer Property ändert. Zum Beispiel von „Nicht verfügbar“ zu „Verfügbar“.ON_CHANGE -Property tritt ein Property-Ereignis ein, wenn sich der Wert oder der Status einer Property ändert.VehiclePropValue mit dem Status „unavailable“ (nicht verfügbar) oder „error“ (Fehler) und einem leeren Wert gesendet werden.SharedMemoryFileCount ist immer 0 . |
|
oneway void onPropertySetError(in VehiclePropErrors errors)
onSetValues mit einem Fehlerergebnis verwendet werden. |
|
oneway void onSupportedValueChange(in List
getMinMaxSupportedValue oder getSupportedValuesLists aufrufen, um die aktualisierten Werte zu erhalten. |
Die VHAL-Implementierung wird durch das VHAL VTS unter VtsHalAutomotiveVehicle_TargetTest.cpp
validiert.
Bei diesem Test wird geprüft, ob die grundlegenden Methoden richtig implementiert sind und die unterstützten Konfigurationen der Property korrekt sind. Der Test wird für alle VHAL-Instanzen auf dem Gerät ausgeführt. AAOS verwendet jedoch nur die Standardinstanz (android.hardware.automotive.vehicle.IVehicle/default
).
Wert der Fahrzeugeigenschaft
Verwenden Sie die Struktur VehiclePropValue
, um den Wert jeder Eigenschaft zu beschreiben. Sie enthält die folgenden Felder:
Feld | Beschreibung |
---|---|
timestamp
| Der Zeitstempel, der die Zeit angibt, zu der das Ereignis stattgefunden hat und mit der SystemClock.elapsedRealtimeNano() -Uhr synchronisiert wurde. |
prop |
Die Property-ID für diesen Wert. |
areaid |
Die Bereichs-ID für diesen Wert. Der Bereich muss einer der unterstützten Bereiche sein, die in der Bereichs-ID-Konfiguration aufgeführt sind, oder 0 für globale Properties. |
value |
Eine Datenstruktur, die den tatsächlichen Property-Wert enthält. Je nach Eigenschaftstyp werden ein oder mehrere Felder in diesem Feld verwendet, um den tatsächlichen Wert zu speichern. Das erste Element in value.int32Values wird beispielsweise für Eigenschaften vom Typ „Int32“ verwendet. Weitere Informationen finden Sie unter Property-Konfigurationen. |
status |
Der Status der Property für den Lesevorgang. Bei Lese-/Schreibeigenschaften kann dies auch für das Schreiben gelten, ist aber nicht garantiert. Die Eigenschaft ist beispielsweise möglicherweise zum Lesen, aber nicht zum Schreiben verfügbar. In diesem Fall ist der Status AVAILABLE und das Wertfeld enthält gültige Informationen.
Informationen zu den möglichen Status finden Sie unter VehiclePropertyStatus . |
Asynchrone getValues- und setValues-Methoden
Die Vorgänge getValues
und setValues
werden asynchron ausgeführt. Das bedeutet, dass die Funktion möglicherweise zurückgegeben wird, bevor der eigentliche Get- oder Set-Vorgang abgeschlossen ist.
Die Ergebnisse des Vorgangs (z. B. der Attributwert für getValues
und der Erfolgs- oder Fehlerstatus für setValues
) werden über die als Argumente übergebenen Callbacks bereitgestellt.
Die Implementierung darf das Ergebnis nicht im Binder-Thread blockieren, der die Anfrage verarbeitet. Stattdessen empfehlen wir, die Anfrage in einer Anfragewarteschlange zu speichern und einen separaten Handler-Thread zu verwenden, um die Anfragen asynchron zu verarbeiten. Weitere Informationen finden Sie in der Referenzimplementierung.
Abbildung 1: Asynchroner Prozess
Große Parcelables
Alle Strukturen mit dem Namen XXXs
, z. B. VehiclePropConfigs
, SetValueRequests
und VehiclePropValues
, werden als LargeParcelable
(oder StableLargeParcelable
) bezeichnet. Jede Struktur stellt eine Liste von Werten dar, die verwendet werden, um große Daten, die die Binder-Beschränkungen (4 KB in der LargeParcelable
-Bibliotheksimplementierung) überschreiten könnten, über Binder-Grenzen hinweg zu übergeben. Jede hat eine ähnliche Strukturdefinition mit den folgenden Feldern.
Anleitung | Beschreibung |
---|---|
payloads |
Liste der Werte, wenn die Wertgröße innerhalb der Speicherbeschränkung eines Bindemittels liegt, oder eine leere Liste. |
sharedMemoryFd |
Nullable-Dateideskriptor, der auf eine Shared-Memory-Datei verweist, in der die serialisierten Nutzlasten gespeichert werden, wenn die Liste der Werte zu groß ist. |
VehiclePropConfigs
ist beispielsweise so definiert:
parcelable VehiclePropConfigs { // The list of vehicle property configs if they fit the binder memory // limitation. VehiclePropConfig[] payloads; // Shared memory file to store configs if they exceed binder memory // limitation. Created by VHAL, readable only at client. Client could keep // the fd opened or keep the FD mapped to access configs. @nullable ParcelFileDescriptor sharedMemoryFd; }
VehiclePropConfigs
enthält entweder nicht leere Nutzlasten oder ein nicht leeres sharedMemoryFd
.
- Wenn
payloads
nicht leer ist, wird darin eine Liste der tatsächlichen Daten gespeichert, also die Property-Konfiguration. - Wenn
sharedMemoryFd
nicht null ist, enthält sie eine Datei mit gemeinsamem Arbeitsspeicher, in der die serialisierte Struktur vonVehiclePropConfigs
gespeichert ist. Die Struktur verwendet die FunktionwriteToParcel
, um ein Parcel zu serialisieren.
Als Java-Client für VHAL übernimmt Car Service die Serialisierung und Deserialisierung für LargeParcelable
. Für VHAL-Implementierungen und native Clients sollte ein LargeParcelable
mit der Bibliothek LargeParcelable
oder einer nützlichen Wrapper-Klasse für die Bibliothek in ParcelableUtils.h
serialisiert und deserialisiert werden.
Ein Beispiel für einen nativen Client, der Anfragen für getValues
parst, die von einem Binder empfangen werden, sieht so aus:
// 'requests' are from the binder. GetValueRequests requests; expected<LargeParcelableBase::BorrowedOwnedObject, ScopedAStatus> deserializedResults = fromStableLargeParcelable(requests); if (deserializedResults.ok()) { const std::vector & getValueRequests = deserializedResults.value().getObject()->payloads; // Use the getValueRequests. } else { // handle error. }
Unten sehen Sie ein Beispiel für eine VHAL-Implementierung, die Ergebnisse für getValues
über den Binder sendet:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }