El VHAL de AIDL se define en android.hardware.automotive.vehicle namespace
.
La interfaz de VHAL se define en IVehicle.aidl
.
A menos que se especifique lo contrario, todos los métodos deben implementarse para una versión específica de VHAL.
Versiones
Versión de Android | Versión más reciente de VHAL | Versión más reciente de la propiedad VHAL | Versión mínima de VHAL compatible |
---|---|---|---|
Android 16 | V4 | V4 | V1 |
Android 15 | V3 | V3 | V1 |
Android 14 | V2 | V2 | V1 |
Android 13 | V1 | (La interfaz de propiedades de VHAL no se divide). | V1 |
SE RECOMIENDA implementar la versión más reciente de VHAL para una versión específica de Android.
Funciones y devoluciones de llamada
Las funciones de VHAL se definen en IVehicle.aidl
.
Método | |
---|---|
VehiclePropConfigs getAllPropConfigs()
|
|
VehiclePropConfigs getPropConfigs(in int[] props)
|
|
void getValues(IVehicleCallback callback, in GetValueRequests requests)
GetValueRequest de forma asíncrona. El resultado se entrega a través del método onGetValues de devolución de llamada. |
|
void setValues(IVehicleCallback callback, in SetValueRequests requests)
SetValueRequest de forma asíncrona. El resultado se entrega a través del método onSetValues de devolución de llamada. |
|
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
maxSharedMemoryFileCount no se usa. |
|
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
|
|
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
|
|
(Nuevo en Android 16)SupportedValuesListResults getSupportedValuesLists(in List
|
|
(Nuevo en Android 16)MinMaxSupportedValueResults getMinMaxSupportedValue(in List
|
|
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
|
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List
|
Las devoluciones de llamada se definen en IVehicleCallback.aidl
y contienen estos métodos.
Método | |
---|---|
oneway void onGetValues(in GetValueResults responses)
Devolución de llamada getValues para entregar resultados de valor de obtención. Se llama cuando algunos de los valores que se recuperarán están listos. |
|
oneway void onSetValues(in SetValueResults responses)
setValues para entregar resultados de valores establecidos. Se llama cuando VHAL termina de controlar algunas de las solicitudes de conjunto de propiedades. |
|
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
CONTINUOUS , un evento de propiedad se produce en función de la tasa de muestreo de suscripción en Hz o la frecuencia de los mensajes del bus del vehículo. También puede ocurrir un evento de propiedad si cambia el estado de una propiedad. Por ejemplo, de no disponible a disponible.ON_CHANGE , un evento de propiedad ocurre cuando cambia el valor o el estado de una propiedad.VehiclePropValue con un estado de no disponible o de error y un valor vacío.SharedMemoryFileCount siempre es 0 . |
|
oneway void onPropertySetError(in VehiclePropErrors errors)
onSetValues con un resultado de error en su lugar. |
|
oneway void onSupportedValueChange(in List
getMinMaxSupportedValue o getSupportedValuesLists para obtener los valores actualizados. |
La implementación de VHAL se valida con la VTS de VHAL en VtsHalAutomotiveVehicle_TargetTest.cpp
.
La prueba verifica que los métodos básicos se implementen correctamente y que las configuraciones de las propiedades compatibles sean correctas. La prueba se ejecuta en todas las instancias de VHAL del dispositivo. Sin embargo, AAOS solo usa la instancia predeterminada (android.hardware.automotive.vehicle.IVehicle/default
).
Valor de la propiedad del vehículo
Usa la estructura VehiclePropValue
para describir el valor de cada propiedad, que tiene estos campos:
Campo | Descripción |
---|---|
timestamp
| Es la marca de tiempo que representa la hora en que ocurrió el evento y se sincroniza con el reloj SystemClock.elapsedRealtimeNano() . |
prop |
Es el ID de la propiedad para este valor. |
areaid |
El ID del área para este valor. El área debe ser una de las áreas admitidas que se indican en la configuración del ID de área o 0 para propiedades globales. |
value |
Es una estructura de datos que contiene el valor real de la propiedad. Según el tipo de propiedad, se usan uno o más campos dentro de este campo para almacenar el valor real. Por ejemplo, el primer elemento en value.int32Values se usa para propiedades de tipo Int32. Para obtener más información, consulta Configuraciones de la propiedad. |
status |
Es el estado de la propiedad para la lectura. En el caso de las propiedades de lectura y escritura, esto también podría aplicarse a la escritura, pero no se garantiza. Por ejemplo, la propiedad podría estar disponible para la lectura, pero no para la escritura. En ese caso, el estado es AVAILABLE y el campo de valor contiene información válida.
Para conocer los estados posibles, consulta
VehiclePropertyStatus . |
getValues y setValues asíncronos
Las operaciones getValues
y setValues
se realizan de forma asíncrona, lo que significa que la función puede mostrarse antes de que se complete la operación de obtención o configuración real.
Los resultados de la operación (por ejemplo, el valor de la propiedad para getValues
y el estado de error o de éxito para setValues
) se entregan a través de las devoluciones de llamadas que se pasan como argumentos.
La implementación no debe bloquearse en el resultado del subproceso de Binder que controla la solicitud. En su lugar, te recomendamos que almacenes la solicitud en una cola de solicitudes y que uses un subproceso de controlador independiente para controlar las solicitudes de forma asíncrona. Consulta la Implementación de referencia para obtener más detalles.
Figura 1: Proceso asíncrono.
Elementos parcelables grandes
Todas las estructuras denominadas XXXs
, como VehiclePropConfigs
, SetValueRequests
y VehiclePropValues
, se denominan LargeParcelable
(o StableLargeParcelable
). Cada una representa una lista de valores que se usan para pasar datos grandes que podrían superar las limitaciones de Binder (4 KB en la implementación de la biblioteca LargeParcelable
) en los límites de Binder. Cada uno tiene una definición de estructura similar que contiene los siguientes campos.
Orientación | Descripción |
---|---|
payloads |
Es una lista de valores cuando el tamaño del valor se ajusta a una limitación de memoria de Binder, o una lista vacía. |
sharedMemoryFd |
Es un descriptor de archivo nulo que apunta a un archivo de memoria compartida que almacena las cargas útiles serializadas si la lista de valores es demasiado grande. |
Por ejemplo, VehiclePropConfigs
se define de la siguiente manera:
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
contiene cargas útiles no vacías o un sharedMemoryFd
no nulo.
- Si
payloads
no está vacío, almacena una lista de los datos reales, que es la configuración de la propiedad. - Si
sharedMemoryFd
no es nulo, contiene un archivo de memoria compartida, que almacena la estructura serializada deVehiclePropConfigs
. La estructura usa la funciónwriteToParcel
para serializar un Parcel.
Como cliente de Java para VHAL, Car Service controla la serialización y deserialización de LargeParcelable
. En el caso de las implementaciones de VHAL y los clientes nativos, se debe serializar y deserializar un LargeParcelable
con la biblioteca LargeParcelable
o una clase de wrapper útil para la biblioteca en ParcelableUtils.h
.
Por ejemplo, un cliente nativo que analiza solicitudes de getValues
recibidas de un vinculador es el siguiente:
// '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. }
A continuación, se muestra una implementación de ejemplo de VHAL que envía resultados para getValues
a través del Binder:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }