O VHAL AIDL é definido em
android.hardware.automotive.vehicle namespace
.
A interface VHAL é definida em
IVehicle.aidl
.
A menos que especificado, todos os métodos precisam ser implementados para uma versão específica da VHAL.
Versões
Versão do Android | Versão mais recente da VHAL | Versão mais recente da propriedade VHAL | Versão mínima compatível da VHAL |
---|---|---|---|
Android 16 | V4 | V4 | V1 |
Android 15 | V3 | V3 | V1 |
Android 14 | V2 | V2 | V1 |
Android 13 | V1 | (Interface de propriedade VHAL não dividida) | V1 |
É RECOMENDADO implementar a versão mais recente da VHAL para uma versão específica do Android.
Funções e callbacks
As funções da VHAL são definidas em
IVehicle.aidl
.
Método | |
---|---|
VehiclePropConfigs getAllPropConfigs()
|
|
VehiclePropConfigs getPropConfigs(in int[] props)
|
|
void getValues(IVehicleCallback callback, in GetValueRequests requests)
GetValueRequest de forma assíncrona. O resultado é enviado pelo método de callback
onGetValues . |
|
void setValues(IVehicleCallback callback, in SetValueRequests requests)
SetValueRequest de forma assíncrona. O resultado é enviado pelo método de callback
onSetValues . |
|
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
maxSharedMemoryFileCount não é usado. |
|
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
|
|
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
|
|
(Novo no Android 16)SupportedValuesListResults getSupportedValuesLists(in List
|
|
(Novo no Android 16)MinMaxSupportedValueResults getMinMaxSupportedValue(in List
|
|
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
|
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
Os callbacks são definidos em
IVehicleCallback.aidl
e contêm estes métodos.
Método | |
---|---|
oneway void onGetValues(in GetValueResults responses)
getValues para entregar resultados de valor de recebimento. Chamado quando alguns dos valores a serem buscados estão prontos. |
|
oneway void onSetValues(in SetValueResults responses)
setValues para entregar resultados de valores definidos. Chamado quando
a VHAL termina de processar algumas das solicitações de definição de propriedade. |
|
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
CONTINUOUS , um evento de propriedade acontece com base na taxa de amostragem de inscrição
em Hz ou na frequência de mensagens do barramento do veículo. Um evento de propriedade também pode acontecer se o status de uma propriedade mudar. Por exemplo, de indisponível para disponível.ON_CHANGE , um evento de propriedade acontece quando o valor
ou o status de uma propriedade muda.VehiclePropValue com um status indisponível ou de erro
e um valor vazio precisa ser entregue.SharedMemoryFileCount é sempre 0 . |
|
oneway void onPropertySetError(in VehiclePropErrors errors)
onSetValues com um resultado de erro em vez disso. |
|
oneway void onSupportedValueChange(in List
getMinMaxSupportedValue ou
getSupportedValuesLists para receber os valores atualizados. |
A implementação da VHAL é validada pelo VTS da VHAL em
VtsHalAutomotiveVehicle_TargetTest.cpp
.
O teste verifica se os métodos básicos estão implementados corretamente e se as configurações de propriedade compatíveis estão corretas. O teste é executado em todas as instâncias de VHAL no dispositivo, mas o AAOS usa apenas a instância padrão (android.hardware.automotive.vehicle.IVehicle/default
).
Valor da propriedade do veículo
Use a estrutura
VehiclePropValue
para descrever o valor de cada propriedade, que tem estes campos:
Campo | Descrição |
---|---|
timestamp
| O carimbo de data/hora que representa o momento em que o evento ocorreu e foi sincronizado com o relógio SystemClock.elapsedRealtimeNano() . |
prop |
O ID da propriedade para esse valor. |
areaid |
O ID da área para esse valor. A área precisa ser uma das áreas aceitas listadas na configuração de ID da área ou 0 para propriedades globais. |
value |
Uma estrutura de dados que contém o valor real da propriedade. Com base no tipo de propriedade, um ou mais campos dentro deste campo são usados para armazenar o valor real. Por exemplo, o primeiro elemento em value.int32Values é usado para propriedades do tipo Int32. Para mais detalhes, consulte
Configurações
de propriedade. |
status |
O status da propriedade para leitura. Para propriedades de leitura/gravação, isso também pode se aplicar à gravação, mas não é garantido. Por exemplo, a propriedade pode estar disponível para leitura, mas não para gravação. Nesse caso, o status é AVAILABLE e o campo de valor contém informações válidas.
Para conferir os possíveis status, consulte
VehiclePropertyStatus . |
getValues e setValues assíncronos
As operações getValues
e setValues
são realizadas de forma assíncrona,
o que significa que a função pode retornar antes que a operação real de get ou set seja concluída.
Os resultados da operação (por exemplo, valor da propriedade para getValues
e status de sucesso ou
erro para setValues
) são entregues pelos callbacks transmitidos como argumentos.
A implementação não pode bloquear o resultado na linha de execução do binder que processa a solicitação. Em vez disso, recomendamos armazenar a solicitação em uma fila e usar uma linha de execução de manipulador separada para processar as solicitações de forma assíncrona. Consulte a Implementação de referência para mais detalhes.
Figura 1. Processo assíncrono.
Parcelables grandes
Todas as estruturas chamadas XXXs
, como VehiclePropConfigs
, SetValueRequests
e VehiclePropValues
, são chamadas de LargeParcelable
(ou StableLargeParcelable
). Cada uma representa uma lista de valores usados para transmitir dados grandes que podem exceder as limitações do binder (4 KB na implementação da biblioteca LargeParcelable
) entre limites do binder. Cada um tem uma definição de estrutura semelhante que contém os seguintes campos.
Orientação | Descrição |
---|---|
payloads |
Lista de valores quando o tamanho do valor se ajusta a uma limitação de memória do binder ou uma lista vazia. |
sharedMemoryFd |
Descritor de arquivo anulável que aponta para um arquivo de memória compartilhada que armazena os payloads serializados se a lista de valores for muito grande. |
Por exemplo, VehiclePropConfigs
é definido como:
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
contém payloads não vazios ou um sharedMemoryFd
não nulo.
- Se
payloads
não estiver vazio, ele vai armazenar uma lista dos dados reais, que é a configuração da propriedade. - Se
sharedMemoryFd
não for nulo, ele vai conter um arquivo de memória compartilhada que armazena a estrutura serializada deVehiclePropConfigs
. A estrutura usa a funçãowriteToParcel
para serializar um Parcel.
Como um cliente Java para VHAL, o Car Service processa a serialização e a desserialização de
LargeParcelable
. Para implementações de VHAL e clientes nativos, um
LargeParcelable
precisa ser serializado e desserializado com a
biblioteca LargeParcelable
ou uma classe wrapper útil para a biblioteca em
ParcelableUtils.h
.
Por exemplo, um cliente nativo que analisa solicitações de getValues
recebidas de um binder
é assim:
// '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. }
Confira abaixo um exemplo de implementação da VHAL que envia resultados para getValues
pelo binder:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }