VHAL interface

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()
Returns a list of all Property Configurations supported by this vehicle HAL.
VehiclePropConfigs getPropConfigs(in int[] props)
Returns a list of Property Configurations for given property IDs.
void getValues(IVehicleCallback callback, in GetValueRequests requests)
Get vehicle property values asynchronously. Handles a batch of GetValueRequest asynchronously. The result is delivered through the onGetValues method of callback.
void setValues(IVehicleCallback callback, in SetValueRequests requests)
Set vehicle property values asynchronously. Handles a batch of SetValueRequest asynchronously. The result is delivered through the onSetValues method of callback.
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
Subscribes to property events with specified options. The subscribe options include property ID, property area ID, and sample rate in Hz (for a continuous property). maxSharedMemoryFileCount isn't used.
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
Unsubscribes previously subscribed property events for specified properties.
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
Not used and can be implemented as no-op.

The callbacks are defined at IVehicleCallback.aidl and contains these methods.

Method
oneway void onGetValues(in GetValueResults responses)
Callback for the getValues function to deliver get value results. Called when some of the values to fetch are ready.
oneway void onSetValues(in SetValueResults responses)
Callback for 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)
Callback for reporting property update events.
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.
For the 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)
Callback for reporting asynchronous property set errors that have no corresponding set request. If we know which set request the error is for, 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 of VehiclePropConfigs. The structure uses the writeToParcel 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, 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::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}