VHAL-Schnittstelle

Die AIDL-VHAL ist in der android.hardware.automotive.vehicle namespace definiert. Die VHAL-Schnittstelle wird unter IVehicle.aidl definiert. Sofern nicht anders angegeben, müssen alle Methoden implementiert werden.

Method
VehiclePropConfigs getAllPropConfigs()
Gibt eine Liste aller Property-Konfigurationen zurück, die von dieser Fahrzeug-HAL unterstützt werden.
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)
Fahrzeugeigenschaftswerte asynchron abrufen. Verarbeitet einen Batch von GetValueRequest asynchron. Das Ergebnis wird über die onGetValues-Methode des Callbacks gesendet.
void setValues(IVehicleCallback callback, in SetValueRequests requests)
Legen Sie Werte für Fahrzeugeigenschaften asynchron fest. Verarbeitet einen Batch von SetValueRequest asynchron. Das Ergebnis wird über die onSetValues-Methode des Callbacks gesendet.
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
Abonniert Property-Ereignisse mit den angegebenen Optionen. Zu den Abooptionen gehören die Property-ID, die Property-Bereichs-ID und die Abtastrate in Hz (für eine kontinuierliche Property). maxSharedMemoryFileCount wird nicht verwendet.
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
Kündigt zuvor abonnierte Property-Ereignisse für bestimmte Properties.
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
Wird nicht verwendet und kann als No-Op implementiert werden.

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

Method
oneway void onGetValues(in GetValueResults responses)
Callback für die Funktion getValues, um Ergebnisse für den Wertabruf 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 der Property-Set-Anfragen abgeschlossen hat.
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
Callback zum Melden von Property-Aktualisierungsereignissen.
CONTINUOUS-Property tritt ein Ereignis auf, das auf der abonnierten Stichprobenrate in Hz oder der Fahrzeugbusnachrichtenfrequenz basiert. Ein Property-Ereignis kann auch auftreten, wenn sich der Status einer Property ändert. Beispiel: von „Nicht verfügbar“ zu „Verfügbar“.
Bei der Property ON_CHANGE wird ein Property-Ereignis erfasst, wenn sich der Wert einer Property oder ihr Status ändert.
SharedMemoryFileCount ist immer 0.
oneway void onPropertySetError(in VehiclePropErrors errors)
Callback zum Melden von asynchronen Fehlern bei Property-Sets, für die keine entsprechende Set-Anfrage vorhanden ist. Wenn wir wissen, für welche Set-Anfrage der Fehler vorliegt, muss stattdessen onSetValues mit einem Fehlerergebnis verwendet werden.

Weitere Informationen finden Sie unter IVehicle.aidl und IVehicleCallback.aidl.

Die VHAL-Implementierung wird vom VHAL-VTS in VtsHalAutomotiveVehicle_TargetTest.cpp validiert. Mit dem Test wird überprüft, ob die grundlegenden Methoden korrekt implementiert sind und die unterstützten Property-Konfigurationen korrekt sind.

Wert der Fahrzeugeigenschaft

Verwenden Sie die Struktur VehiclePropValue, um den Wert jeder Property zu beschreiben. Sie enthält die folgenden Felder:

Feld Beschreibung
timestamp Der Zeitstempel, der die Zeit des Ereignisses angibt und mit der SystemClock.elapsedRealtimeNano()-Uhr synchronisiert ist.
prop Die Property-ID für diesen Wert.
areaid Die Bereichs-ID für diesen Wert. Das Gebiet muss einem der unterstützten Gebiete entsprechen, die in der Bereichs-ID-Konfiguration aufgeführt sind, oder 0 für globale Properties.
value Eine Datenstruktur mit dem tatsächlichen Property-Wert. 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 Properties vom Typ „Int32“ verwendet. Weitere Informationen finden Sie unter Property-Konfigurationen.

Asynchrone getValues und setValues

Die Vorgänge getValues und setValues werden asynchron ausgeführt. Das bedeutet, dass die Funktion möglicherweise zurückgegeben wird, bevor der eigentliche Abruf- oder Setzvorgang abgeschlossen ist. Die Ergebnisse des Vorgangs (z. B. der Attributwert für getValues und der Erfolg- oder Fehlerstatus für setValues) werden über die als Argumente übergebenen Rückrufe gesendet.

Die Implementierung darf im Binder-Thread, der die Anfrage verarbeitet, nicht auf das Ergebnis warten. 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 Vorgang.

Große Pakete

Alle Strukturen mit dem Namen XXXs, z. B. VehiclePropConfigs, SetValueRequests und VehiclePropValues, werden LargeParcelable (oder StableLargeParcelable) genannt. Jede Struktur stellt eine Liste von Werten dar, die zur Übergabe großer Daten verwendet werden, die die Binderbeschränkungen (4 KB in der LargeParcelable-Bibliotheksimplementierung) über Bindergrenzen überschreiten. Jedes hat eine ähnliche Strukturdefinition, die die folgenden Felder enthält.

Anleitung Beschreibung
payloads Liste von Werten, wenn die Größe des Werts in die Speicherbeschränkung des Binders passt, oder eine leere Liste.
sharedMemoryFd Nullbarer Dateideskriptor, der auf eine freigegebene Arbeitsspeicherdatei verweist, in der die serialisierten Nutzlasten gespeichert werden, wenn die Liste der Werte zu groß ist.

Angenommen, VehiclePropConfigs ist 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 eine sharedMemoryFd, die nicht null ist.

  • Wenn payloads nicht leer ist, wird eine Liste der tatsächlichen Daten gespeichert, also die Property-Konfiguration.
  • Wenn sharedMemoryFd nicht null ist, enthält es eine gemeinsam genutzte Arbeitsspeicherdatei, in der die serialisierte Struktur von VehiclePropConfigs gespeichert ist. In der Struktur wird die Funktion writeToParcel verwendet, um ein Paket 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 serialisiert und mit der Bibliothek LargeParcelable oder einer nützlichen Wrapper-Klasse für die Bibliothek in ParcelableUtils.h serialisiert und deserialisiert werden.

Ein nativer Client, der Anfragen für getValues analysiert, die von einem Binder empfangen wurden, sieht beispielsweise so aus:

// 'requests' are from the binder.
GetValueRequests requests;
expected, 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.
}