AIDL VHAL 在 android.hardware.automotive.vehicle namespace
中定义。
VHAL 接口在 IVehicle.aidl
中定义。
除非另有说明,否则必须实现所有方法。
方法 | |
---|---|
VehiclePropConfigs getAllPropConfigs()
|
|
VehiclePropConfigs getPropConfigs(in int[] props)
|
|
void getValues(IVehicleCallback callback, in GetValueRequests requests)
GetValueRequest 。结果通过回调的 onGetValues 方法传递。 |
|
void setValues(IVehicleCallback callback, in SetValueRequests requests)
SetValueRequest 。结果通过回调的 onSetValues 方法传递。 |
|
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
maxSharedMemoryFileCount 。 |
|
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
|
|
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
|
回调在 IVehicleCallback.aidl
中定义,并包含这些方法。
方法 | |
---|---|
oneway void onGetValues(in GetValueResults responses)
getValues 函数的回调。在要提取的某些值准备就绪时调用。 |
|
oneway void onSetValues(in SetValueResults responses)
setValues 函数的回调。在 VHAL 处理完某些属性设置请求时调用。 |
|
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
CONTINUOUS 属性,系统会根据订阅采样率(以 Hz 为单位)或车载总线消息频率发生属性事件。如果属性的状态发生变化,也有可能发生属性事件。例如,从不可用变成可用。ON_CHANGE 属性,当属性值或属性的状态发生更改时,就会发生属性事件。SharedMemoryFileCount 始终为 0 。 |
|
oneway void onPropertySetError(in VehiclePropErrors errors)
onSetValues ,而不是此方法。 |
如需了解详情,请参阅 IVehicle.aidl 和 IVehicleCallback.aidl。
VHAL 实现由 VtsHalAutomotiveVehicle_TargetTest.cpp 中的 VHAL VTS 进行验证。此测试可验证基本方法是否已正确实现,以及支持的属性配置是否正确。
车辆属性值
请使用 VehiclePropValue
结构描述每个属性的值,其中包含以下字段:
字段 | 说明 |
---|---|
timestamp
| 表示事件发生时间的时间戳,与 SystemClock.elapsedRealtimeNano() 时钟同步。 |
prop |
此值的属性 ID。 |
areaid |
此值的区域 ID。该区域必须是区域 ID 配置中列出的某个受支持区域;对于全局属性,该区域必须是 0 。 |
value |
包含实际属性值的数据结构。根据属性类型,此字段中的一个或多个字段将用于存储实际值。例如,value.int32Values 中的第一个元素用于 Int32 类型属性。如需了解详情,请参阅属性配置。 |
异步 getValues 和 setValues
getValues
和 setValues
操作是异步执行的,这意味着函数可能会在实际的 get 或 set 操作完成之前返回结果。操作结果(例如,getValues
的属性值和 setValues
的成功或错误状态)通过作为参数传递的回调传递。
实现不得对处理请求的 binder 线程中的结果进行阻塞。相反,我们建议您将请求存储在请求队列中,并使用单独的处理程序线程异步处理请求。如需了解详情,请参阅参考实现。
图 1. 异步进程。
大型 Parcelable
所有名为 XXXs
的结构(例如 VehiclePropConfigs
、SetValueRequests
和 VehiclePropValues
)都称为 LargeParcelable
(或 StableLargeParcelable
)。每个结构代表一个值列表,用于跨 binder 边界传递可能超出 binder 限制(在 LargeParcelable
库实现中为 4KB)的大型数据。每个结构都具有类似的结构定义,其中包含以下字段。
指南 | 说明 |
---|---|
payloads |
当值大小符合 binder 内存限制时的值列表或空列表。 |
sharedMemoryFd |
指向一个共享内存文件的可为 null 性文件描述符,该文件在值列表过大时存储序列化载荷。 |
例如,VehiclePropConfigs
的定义如下:
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
包含非空载荷或非 null sharedMemoryFd
。
- 如果
payloads
不为空,它会存储实际数据的列表,即属性配置。 - 如果
sharedMemoryFd
不为 null,它会包含一个共享内存文件,其中存储了VehiclePropConfigs
的序列化结构。该结构使用writeToParcel
函数来序列化 Parcel。
作为 VHAL 的 Java 客户端,汽车服务会处理 LargeParcelable
的序列化和反序列化。对于 VHAL 实现和原生客户端,应使用 LargeParcelable
库或该库在 ParcelableUtils.h
中的实用封装容器类对 LargeParcelable
进行序列化和反序列化。
例如,原生客户端解析从 binder 接收的 getValues
的请求如下所示:
// '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. }
下面是一个通过 binder 发送 getValues
结果的 VHAL 实现示例:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }