The AIDL VHAL is defined in the
android.hardware.automotive.vehicle namespace
.
The VHAL interface is defined at
IVehicle.aidl
.
Unless specified, all methods must be implemented.
Method | |
---|---|
VehiclePropConfigs getAllPropConfigs()
|
|
VehiclePropConfigs getPropConfigs(in int[] props)
|
|
void getValues(IVehicleCallback callback, in GetValueRequests requests)
GetValueRequest asynchronously. The result is delivered through the
onGetValues method of callback. |
|
void setValues(IVehicleCallback callback, in SetValueRequests requests)
SetValueRequest asynchronously. The result is delivered through the
onSetValues method of callback. |
|
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
maxSharedMemoryFileCount isn't used. |
|
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
|
|
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
|
The callbacks are defined at
IVehicleCallback.aidl
and contains these methods.
Method | |
---|---|
oneway void onGetValues(in GetValueResults responses)
getValues function to deliver get value results. Called
when some of the values to fetch are ready. |
|
oneway void onSetValues(in SetValueResults responses)
setValues function to deliver set value results. Called when
VHAL has finished handling some of the property set requests. |
|
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
CONTINUOUS property, a property event happens based on subscribe sample rate
in Hz or vehicle bus message frequency. A property event might also happen if a property's
status changes. For example, from unavailable to available.ON_CHANGE property, a property event happens when a property's value
or a property's status changes.SharedMemoryFileCount is always 0 . |
|
oneway void onPropertySetError(in VehiclePropErrors errors)
onSetValues with an
error result must be used instead of this. |
For more information, see IVehicle.aidl and IVehicleCallback.aidl.
The VHAL implementation is validated by the VHAL VTS at VtsHalAutomotiveVehicle_TargetTest.cpp. The test verifies that basic methods are implemented correctly and the supported property configurations are correct.
Vehicle property value
Use the
VehiclePropValue
structure to describe each property's value, which has these fields:
Field | Description |
---|---|
timestamp
| The timestamp representing the time the event happened and synchronized with the
SystemClock.elapsedRealtimeNano() clock. |
prop |
The property ID for this value. |
areaid |
The area ID for this value. The area must be one of the supported areas listed in the area
ID configuration, or 0 for global properties. |
value |
A data structure containing the actual property value. Based on the property type, one or
more fields within this field are used to store the actual value. For example, the first
element in value.int32Values is used for Int32 type properties. For details, see
Property
Configurations. |
Asynchronous getValues and setValues
The getValues
and setValues
operations are performed asynchronously,
meaning that the function might return before the actual get or set operation is completed.
The operation results (for example, property value for getValues
and success or
error status for setValues
) are delivered through the callbacks passed as arguments.
Implementation must not block on the result in the binder thread that handles the request. Instead, we recommend you store the request in a request queue and use a separate handler thread to handle the requests asynchronously. See the Reference Implementation for details.
Figure 1. Asynchronous process.
Large parcelables
All structures named XXXs
, such as VehiclePropConfigs
,
SetValueRequests
, and VehiclePropValues
are called
LargeParcelable
(or, StableLargeParcelable
). Each represents a list of
values used to pass large data that might exceed binder limitations (4KB in the
LargeParcelable
library implementation) across binder boundaries. Each has a similar
structure definition which contains the following fields.
Guidance | Description |
---|---|
payloads |
List of values when value size fits within a binder memory limitation, or an empty list. |
sharedMemoryFd |
Nullable file descriptor pointing to a shared memory file that stores the serialized payloads if the list of values are too large. |
For example, VehiclePropConfigs
is defined as:
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
contains either non-empty payloads or a non-null
sharedMemoryFd
.
- If
payloads
isn't empty, it stores a list of the actual data, which is the property config. - If
sharedMemoryFd
isn't null, it contains a shared memory file, which stores the serialized structure ofVehiclePropConfigs
. The structure uses thewriteToParcel
function to serialize a Parcel.
As a Java client for VHAL, Car Service handles the serialization and deserialization for
LargeParcelable
. For VHAL implementations and native clients, a
LargeParcelable
should be serialized and deserialized with the
LargeParcelable
library or a useful wrapper class for the library in
ParcelableUtils.h
.
For example, a native client parsing requests for getValues
received from a binder
is as follows:
// '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 sample VHAL implementation that sends results for getValues
through the binder is
shown below:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }