AIDL VHAL jest zdefiniowany w android.hardware.automotive.vehicle namespace.
Interfejs VHAL jest zdefiniowany na stronie IVehicle.aidl.
O ile nie określono inaczej, wszystkie metody muszą być zaimplementowane w określonej wersji VHAL.
Wersje
| Wersja Androida | Najnowsza wersja VHAL | Najnowsza wersja właściwości VHAL | Minimalna zgodna wersja VHAL |
|---|---|---|---|
| Android 16 | V4 | V4 | Wersja 1 |
| Android 15 | V3 | V3 | Wersja 1 |
| Android 14 | Wersja 2 | Wersja 2 | Wersja 1 |
| Android 13 | Wersja 1 | (Interfejs właściwości VHAL nie jest podzielony) | Wersja 1 |
ZALECAMY wdrożenie najnowszej wersji VHAL dla konkretnej wersji Androida.
Funkcje i wywołania zwrotne
Funkcje VHAL są zdefiniowane na stronie IVehicle.aidl.
| Metoda | |
|---|---|
VehiclePropConfigs getAllPropConfigs()
|
|
VehiclePropConfigs getPropConfigs(in int[] props)
|
|
void getValues(IVehicleCallback callback, in GetValueRequests requests)
GetValueRequest. Wynik jest przekazywany za pomocą metody onGetValues wywołania zwrotnego. |
|
void setValues(IVehicleCallback callback, in SetValueRequests requests)
SetValueRequest asynchronicznie. Wynik jest przekazywany za pomocą metody onSetValues wywołania zwrotnego. |
|
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
maxSharedMemoryFileCount nie jest używana. |
|
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
|
|
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
|
|
(Nowość w Androidzie 16)SupportedValuesListResults getSupportedValuesLists(in List
|
|
(Nowość w Androidzie 16)MinMaxSupportedValueResults getMinMaxSupportedValue(in List
|
|
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
|
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
|
Funkcje zwrotne są zdefiniowane w IVehicleCallback.aidl i zawierają te metody.
| Metoda | |
|---|---|
oneway void onGetValues(in GetValueResults responses)
getValues, które dostarcza wyniki wartości. Wywoływana, gdy niektóre z wartości do pobrania są gotowe. |
|
oneway void onSetValues(in SetValueResults responses)
setValues, które dostarcza wyniki o ustalonej wartości. Wywoływana, gdy VHAL zakończy obsługę niektórych żądań ustawienia właściwości. |
|
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
CONTINUOUS zdarzenie usługi występuje na podstawie częstotliwości próbkowania subskrypcji
w Hz lub częstotliwości wiadomości magistrali pojazdu. Zdarzenie usługi może też wystąpić, jeśli zmieni się stan usługi. Na przykład z niedostępnego na dostępny.ON_CHANGE zdarzenie usługi występuje, gdy zmieni się wartość lub stan usługi.VehiclePropValue ze stanem niedostępności lub błędu i pustą wartością.SharedMemoryFileCount to zawsze 0. |
|
oneway void onPropertySetError(in VehiclePropErrors errors)
onSetValues z wynikiem błędu. |
|
oneway void onSupportedValueChange(in List
getMinMaxSupportedValue lub getSupportedValuesLists, aby uzyskać zaktualizowane wartości. |
|
Implementacja VHAL jest weryfikowana przez VHAL VTS na stronie VtsHalAutomotiveVehicle_TargetTest.cpp.
Test sprawdza, czy podstawowe metody są prawidłowo zaimplementowane, a obsługiwane konfiguracje usługi są poprawne. Test jest przeprowadzany na wszystkich instancjach VHAL na urządzeniu, ale AAOS używa tylko instancji domyślnej (android.hardware.automotive.vehicle.IVehicle/default).
Wartość właściwości pojazdu
Użyj struktury
VehiclePropValue, aby opisać wartość każdej właściwości. Struktura ta zawiera te pola:
| Pole | Opis |
|---|---|
timestamp
| Sygnatura czasowa reprezentująca czas wystąpienia zdarzenia zsynchronizowany z zegarem SystemClock.elapsedRealtimeNano(). |
prop |
Identyfikator usługi dla tej wartości. |
areaid |
Identyfikator obszaru dla tej wartości. Obszar musi być jednym z obsługiwanych obszarów wymienionych w konfiguracji identyfikatora obszaru lub 0 w przypadku usług globalnych. |
value |
Struktura danych zawierająca rzeczywistą wartość usługi. W zależności od typu właściwości do przechowywania rzeczywistej wartości używane jest co najmniej 1 pole w tym polu. Na przykład pierwszy element w value.int32Values jest używany w przypadku właściwości typu Int32. Szczegółowe informacje znajdziesz w sekcji Konfiguracje usługi. |
status |
Stan usługi do odczytu. W przypadku właściwości z uprawnieniami do odczytu i zapisu może to również dotyczyć zapisu, ale nie jest to gwarantowane. Na przykład właściwość może być dostępna do odczytu, ale nie do zapisu. W takim przypadku stan to AVAILABLE, a pole wartości zawiera prawidłowe informacje.
Możliwe stany znajdziesz w sekcji
VehiclePropertyStatus. |
Asynchroniczne metody getValues i setValues
Operacje getValues i setValues są wykonywane asynchronicznie, co oznacza, że funkcja może zwrócić wartość przed zakończeniem rzeczywistej operacji pobierania lub ustawiania.
Wyniki operacji (np. wartość właściwości dla getValues i stan powodzenia lub błędu dla setValues) są przekazywane za pomocą wywołań zwrotnych przekazywanych jako argumenty.
Implementacja nie może blokować wyniku w wątku powiązanym, który obsługuje żądanie. Zamiast tego zalecamy przechowywanie żądania w kolejce żądań i używanie osobnego wątku obsługi do asynchronicznego obsługiwania żądań. Szczegółowe informacje znajdziesz w implementacji referencyjnej.
Rysunek 1. Proces asynchroniczny.
Duże obiekty Parcelable
Wszystkie struktury o nazwie XXXs, takie jak VehiclePropConfigs, SetValueRequests i VehiclePropValues, są nazywane LargeParcelable (lub StableLargeParcelable). Każda z nich reprezentuje listę wartości używanych do przekazywania dużych ilości danych, które mogą przekraczać ograniczenia modułu Binder (4 KB w implementacji biblioteki LargeParcelable), przez granice modułu Binder. Każda z nich ma podobną definicję struktury, która zawiera te pola:
| Wskazówki | Opis |
|---|---|
payloads |
Lista wartości, jeśli rozmiar wartości mieści się w limicie pamięci modułu, lub pusta lista. |
sharedMemoryFd |
Deskryptor pliku z wartością null wskazujący plik pamięci współdzielonej, który przechowuje serializowane ładunki, jeśli lista wartości jest zbyt długa. |
Na przykład VehiclePropConfigs jest zdefiniowane jako:
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 zawiera niepuste ładunki lub niepustą wartość sharedMemoryFd.
- Jeśli
payloadsnie jest pusta, przechowuje listę rzeczywistych danych, czyli konfigurację usługi. - Jeśli
sharedMemoryFdnie jest wartością null, zawiera plik pamięci współdzielonej, w którym jest przechowywana serializowana strukturaVehiclePropConfigs. Struktura używa funkcjiwriteToParceldo serializacji obiektu Parcel.
Jako klient VHAL w języku Java usługa Car Service obsługuje serializację i deserializację dla LargeParcelable. W przypadku implementacji VHAL i klientów natywnych element LargeParcelable powinien być serializowany i deserializowany za pomocą biblioteki LargeParcelable lub przydatnej klasy opakowującej dla biblioteki w ParcelableUtils.h.
Na przykład klient natywny analizujący żądania dotyczące getValues otrzymane z bindera
wygląda tak:
// '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. }
Przykładowe wdrożenie VHAL, które wysyła wyniki dla getValues za pomocą bindera, jest pokazane poniżej:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }