VHAL-Schnittstelle

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()
Gibt eine Liste aller von dieser Fahrzeug-HAL unterstützten Property-Konfigurationen zurück.
VehiclePropConfigs getPropConfigs(in int[] props)
Gibt eine Liste von Property-Konfigurationen für die angegebenen Property-IDs zurück.
void getValues(IVehicleCallback callback, in GetValueRequests requests)
Ruft Fahrzeugeigenschaftswerte asynchron ab. Verarbeitet einen Batch von GetValueRequest asynchron. Das Ergebnis wird über die onGetValues-Methode des Callbacks zurückgegeben.
void setValues(IVehicleCallback callback, in SetValueRequests requests)
Legt Fahrzeugeigenschaftswerte asynchron fest. Verarbeitet einen Batch von SetValueRequest asynchron. Das Ergebnis wird über die onSetValues-Methode des Callbacks zurückgegeben.
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
Abonniert Attributereignisse mit den angegebenen Optionen. Die Abo-Optionen umfassen die Property-ID, die Property-Bereichs-ID und die Samplingrate in Hz (für eine kontinuierliche Property). maxSharedMemoryFileCount wird nicht verwendet.
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
Meldet zuvor abonnierte Property-Ereignisse für die angegebenen Properties ab.
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
Wird nicht verwendet und kann als No-Op implementiert werden.
(Neu in Android 16)
SupportedValuesListResults getSupportedValuesLists(in List propIdAreaIds)
Ruft die Listen der unterstützten Werte für die angegebenen Paare aus Property-ID und Bereichs-ID ab.
Eingeführt in VHAL V4.
(Neu in Android 16)
MinMaxSupportedValueResults getMinMaxSupportedValue(in List propIdAreaIds)
Ruft die minimalen und maximalen unterstützten Werte für die angegebenen Property-ID- und Bereichs-ID-Paare ab.
Eingeführt in VHAL V4.
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
Registriert einen Callback, der aufgerufen wird, wenn sich die unterstützten Werte ändern.
Eingeführt in VHAL V4.
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
Hebt die Registrierung des unterstützten Rückrufs für Wertänderungen auf.
Eingeführt in VHAL V4.

Die Callbacks sind unter IVehicleCallback.aidl definiert und enthalten diese Methoden.

Methode
oneway void onGetValues(in GetValueResults responses)
Callback für die Funktion getValues, um Ergebnisse für „get value“ zu liefern. Wird aufgerufen, wenn einige der abzurufenden Werte bereit sind.
oneway void onSetValues(in SetValueResults responses)
Callback für die Funktion 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)
Callback zum Melden von Ereignissen zur Aktualisierung von Eigenschaften.
Bei der
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“.
Für die ON_CHANGE-Property tritt ein Property-Ereignis ein, wenn sich der Wert oder der Status einer Property ändert.
Dieses Feld sollte auch verwendet werden, um Ereignisse für Änderungen des Property-Status zu senden, z. B. wenn die Property nicht mehr verfügbar ist oder ein Fehler beim Lesen auftritt. In diesem Fall sollte ein 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)
Callback zum Melden asynchroner Fehler beim Festlegen von Attributen, für die keine entsprechende Set-Anfrage vorhanden ist. Wenn wir wissen, für welche Set-Anfrage der Fehler auftritt, muss stattdessen onSetValues mit einem Fehlerergebnis verwendet werden.
oneway void onSupportedValueChange(in List propIdAreaIds)
Callback zum Melden von Änderungen am minimalen und maximalen unterstützten Wert oder an der Liste der unterstützten Werte. Der Aufrufer sollte 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 von VehiclePropConfigs gespeichert ist. Die Struktur verwendet die Funktion writeToParcel, 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::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}