VHAL-Schnittstelle

Die AIDL-VHAL ist in der android.hardware.automotive.vehicle namespace definiert. Die VHAL-Schnittstelle ist 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 diesem 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)
Werte für Fahrzeugeigenschaften 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 Bearbeitung einiger Anfragen für Property-Sets abgeschlossen hat.
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
Callback zum Melden von Ereignissen für Hotelaktualisierungen.
CONTINUOUS-Property tritt ein Ereignis basierend auf der abonnierten Stichprobenrate in Hz oder der Fahrzeugbus-Nachrichtenfrequenz auf. 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 ausgelöst, wenn sich der Wert oder der Status einer Property ä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. Dabei wird überprüft, ob die grundlegenden Methoden richtig implementiert 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 Gebiets-ID für diesen Wert. Das Gebiet muss eine der in der Konfiguration der Gebiets-ID aufgeführten unterstützten Gebieten sein oder 0 für globale Properties.
value Eine Datenstruktur mit dem tatsächlichen Property-Wert. Je nach Property-Typ 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 Prozess.

Große Pakete

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 zum Übertragen großer Daten verwendet werden, die die Bindungsbeschränkungen (4 KB in der LargeParcelable-Bibliotheksumsetzung) über Bindungsgrenzen hinweg überschreiten können. Jede hat eine ähnliche Strukturdefinition mit den folgenden Feldern.

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 nicht nullwertige sharedMemoryFd.

  • 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 der Car-Dienst die Serialisierung und Deserialisierung für LargeParcelable. Bei VHAL-Implementierungen und nativen Clients sollte LargeParcelable mit der LargeParcelable-Bibliothek 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<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.
}