Интерфейс AIDL VHAL определен в android.hardware.automotive.vehicle namespace . Интерфейс VHAL определен в IVehicle.aidl . Если не указано иное, все методы должны быть реализованы для конкретной версии VHAL.
Версии
| версия для Android | Последняя версия VHAL | Последняя версия свойств VHAL | Минимальная совместимая версия VHAL |
|---|---|---|---|
| Android 16 | V4 | V4 | В1 |
| Android 15 | V3 | V3 | В1 |
| Android 14 | V2 | V2 | В1 |
| Android 13 | В1 | (Интерфейс свойств VHAL не разделен) | В1 |
РЕКОМЕНДУЕТСЯ использовать последнюю версию VHAL для конкретной версии Android.
Функции и обратные вызовы
Функции 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) | |
( Новое в Android 16 )SupportedValuesListResults getSupportedValuesLists(in List | |
( Новое в Android 16 )MinMaxSupportedValueResults getMinMaxSupportedValue(in List | |
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List | |
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List | |
Функции обратного вызова определены в файле 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 активности событие, связанное с активностью объекта, происходит на основе частоты дискретизации подписки в Гц или частоты сообщений в шине транспортного средства. Событие, связанное с активностью объекта, также может произойти при изменении его статуса, например, с «недоступен» на «доступен».ON_CHANGE событие срабатывает при изменении значения свойства или его статуса.VehiclePropValue со статусом «недоступен» или «ошибка» и пустым значением.SharedMemoryFileCount всегда равно 0 . | |
oneway void onPropertySetError(in VehiclePropErrors errors)onSetValues с результатом ошибки. | |
oneway void onSupportedValueChange(in ListgetMinMaxSupportedValue или getSupportedValuesLists , чтобы получить обновленные значения. | |
Реализация VHAL проверяется с помощью VHAL VTS, расположенного в файле VtsHalAutomotiveVehicle_TargetTest.cpp .
Тест проверяет корректность реализации базовых методов и правильность поддерживаемых конфигураций свойств. Тест выполняется для всех экземпляров VHAL на устройстве, однако AAOS использует только экземпляр по умолчанию ( android.hardware.automotive.vehicle.IVehicle/default ).
Стоимость имущества транспортного средства
Для описания значения каждого свойства используйте структуру VehiclePropValue , которая содержит следующие поля:
| Поле | Описание |
|---|---|
timestamp | Временная метка, представляющая время, когда произошло событие, синхронизированная с часами SystemClock.elapsedRealtimeNano() . |
prop | Идентификатор свойства для этого значения. |
areaid | Идентификатор области для этого значения. Область должна быть одной из поддерживаемых областей, перечисленных в конфигурации идентификатора области, или 0 для глобальных свойств. |
value | Структура данных, содержащая фактическое значение свойства. В зависимости от типа свойства, для хранения фактического значения используется одно или несколько полей внутри этого поля. Например, первый элемент в value.int32Values используется для свойств типа Int32. Подробнее см. раздел «Конфигурации свойств» . |
status | Статус свойства для чтения. Для свойств с возможностью чтения/записи это может также относиться и к свойствам с возможностью записи, но не гарантируется, например, свойство может быть доступно для чтения, но недоступно для записи. В таком случае статус — AVAILABLE , и поле значения содержит достоверную информацию. Возможные статусы см. в разделе VehiclePropertyStatus . |
Асинхронные методы getValues и setValues
Операции getValues и setValues выполняются асинхронно, это означает, что функция может завершиться до того, как будет выполнена фактическая операция получения или установки значения. Результаты операций (например, значение свойства для getValues и статус успеха или ошибки для setValues ) передаются через коллбэки, передаваемые в качестве аргументов.
Реализация не должна блокироваться на результатах в потоке связывания, обрабатывающем запрос. Вместо этого мы рекомендуем сохранять запрос в очереди запросов и использовать отдельный поток обработчика для асинхронной обработки запросов. Подробности см. в эталонной реализации .
Рисунок 1. Асинхронный процесс.
Крупногабаритные посылки
Все структуры с именем XXXs , такие как VehiclePropConfigs , SetValueRequests и VehiclePropValues называются LargeParcelable (или StableLargeParcelable ). Каждая из них представляет собой список значений, используемых для передачи больших объемов данных, которые могут превышать ограничения связывателя (4 КБ в реализации библиотеки LargeParcelable ), через границы связывателей. Каждая из них имеет аналогичное определение структуры, содержащее следующие поля.
| Руководство | Описание |
|---|---|
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 содержит либо непустые полезные нагрузки, либо непустой sharedMemoryFd .
- Если
payloadsне пуста, она хранит список фактических данных, представляющих собой конфигурацию свойств. - Если
sharedMemoryFdне равен null, он содержит файл разделяемой памяти, в котором хранится сериализованная структураVehiclePropConfigs. Эта структура использует функциюwriteToParcelдля сериализации объекта Parcel.
В качестве Java-клиента для VHAL, Car Service обрабатывает сериализацию и десериализацию LargeParcelable . Для реализаций VHAL и нативных клиентов сериализацию и десериализацию LargeParcelable следует выполнять с помощью библиотеки LargeParcelable или полезного класса-обертки для этой библиотеки в ParcelableUtils.h .
Например, обработка запросов на получение 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. }
Ниже показан пример реализации VHAL, которая отправляет результаты функции getValues через связыватель:
std::vectorresults = getResults(); GetValueResults parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults); if (status.isOk()) { // Send parcelableResults through callback. } else { // Handle error. }