VHAL-интерфейс

Интерфейс 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()
Возвращает список всех конфигураций свойств, поддерживаемых HAL данного транспортного средства.
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 propIdAreaIds)
Получает списки поддерживаемых значений для указанных пар идентификаторов свойства и области.
Впервые представлен в VHAL V4.
( Новое в Android 16 )
MinMaxSupportedValueResults getMinMaxSupportedValue(in List propIdAreaIds)
Получает минимальное и максимальное поддерживаемые значения для указанных пар идентификаторов объекта недвижимости и области.
Впервые представлен в VHAL V4.
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
Регистрирует функцию обратного вызова, которая будет вызываться при изменении поддерживаемых значений.
Впервые представлен в VHAL V4.
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
Отменяет регистрацию функции обратного вызова для изменения поддерживаемого значения.
Впервые представлен в VHAL V4.

Функции обратного вызова определены в файле 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 List propIdAreaIds)
Функция обратного вызова для сообщения об изменениях минимального и максимального поддерживаемых значений или списка поддерживаемых значений. Вызывающая сторона должна вызвать getMinMaxSupportedValue или 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::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}