Interface VHAL

Le VHAL AIDL est défini dans le fichier android.hardware.automotive.vehicle namespace. L'interface VHAL est définie à IVehicle.aidl. Sauf indication contraire, toutes les méthodes doivent être implémentées.

Méthode
VehiclePropConfigs getAllPropConfigs()
Renvoie la liste de toutes les configurations de propriétés acceptées par l'HAL de ce véhicule.
VehiclePropConfigs getPropConfigs(in int[] props)
Renvoie une liste de configurations de propriétés pour des ID de propriété donnés.
void getValues(IVehicleCallback callback, in GetValueRequests requests)
Obtenez les valeurs des propriétés d'un véhicule de manière asynchrone. Gère un lot de GetValueRequest de manière asynchrone. Le résultat est fourni via la méthode de rappel onGetValues.
void setValues(IVehicleCallback callback, in SetValueRequests requests)
Définissez les valeurs des propriétés d'un véhicule de manière asynchrone. Gère un lot de SetValueRequest de manière asynchrone. Le résultat est fourni via la méthode de rappel onSetValues.
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
S'abonne aux événements de la propriété avec les options spécifiées. Les options d'abonnement incluent l'ID de la propriété, l'ID de la zone de la propriété et la fréquence d'échantillonnage en Hz (pour une propriété continue). maxSharedMemoryFileCount n'est pas utilisé.
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
Désinscrit les événements de propriété précédemment souscrits pour les propriétés spécifiées.
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
Non utilisé et peut être implémenté comme une opération sans effet.

Les rappels sont définis à l'emplacement IVehicleCallback.aidl et contiennent ces méthodes.

Méthode
oneway void onGetValues(in GetValueResults responses)
Rappel de la fonction getValues pour obtenir les résultats de la valeur. Appelé lorsque certaines des valeurs à extraire sont prêtes.
oneway void onSetValues(in SetValueResults responses)
Rappel de la fonction setValues pour fournir les résultats de la valeur définie. Appelé lorsque le VHAL a fini de traiter certaines requêtes d'ensemble de propriétés.
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
Rappel pour signaler les événements de mise à jour des établissements.
CONTINUOUS, un événement de propriété se produit en fonction du taux d'échantillonnage d'abonnement en Hz ou de la fréquence des messages du bus du véhicule. Un événement de propriété peut également se produire si l'état d'une propriété change. Par exemple, de "non disponible" à "disponible".
Pour la propriété ON_CHANGE, un événement de propriété se produit lorsque la valeur ou l'état d'une propriété change.
SharedMemoryFileCount est toujours 0.
oneway void onPropertySetError(in VehiclePropErrors errors)
Rappel pour signaler les erreurs d'ensemble de propriétés asynchrones qui n'ont pas de requête d'ensemble correspondante. Si nous savons à quelle requête d'ensemble l'erreur est destinée, onSetValues avec un résultat d'erreur doit être utilisé à la place.

Pour en savoir plus, consultez IVehicle.aidl et IVehicleCallback.aidl.

L'implémentation de VHAL est validée par le VTS VHAL dans VtsHalAutomotiveVehicle_TargetTest.cpp. Le test vérifie que les méthodes de base sont implémentées correctement et que les configurations de propriété compatibles sont correctes.

Valeur de la propriété du véhicule

Utilisez la structure VehiclePropValue pour décrire la valeur de chaque propriété, qui comporte les champs suivants:

Champ Description
timestamp Horodatage représentant l'heure à laquelle l'événement s'est produit et synchronisé avec l'horloge SystemClock.elapsedRealtimeNano().
prop ID de propriété pour cette valeur.
areaid Identifiant de zone pour cette valeur. La zone doit être l'une des zones compatibles listées dans la configuration de l'ID de zone, ou 0 pour les propriétés globales.
value Structure de données contenant la valeur réelle de la propriété. En fonction du type de propriété, un ou plusieurs champs de ce champ sont utilisés pour stocker la valeur réelle. Par exemple, le premier élément de value.int32Values est utilisé pour les propriétés de type Int32. Pour en savoir plus, consultez la section Configurations de propriété.

getValues et setValues asynchrones

Les opérations getValues et setValues sont effectuées de manière asynchrone, ce qui signifie que la fonction peut être renvoyée avant la fin de l'opération d'obtention ou de définition. Les résultats de l'opération (par exemple, la valeur de la propriété pour getValues et l'état de réussite ou d'erreur pour setValues) sont transmis via les rappels transmis en tant qu'arguments.

L'implémentation ne doit pas bloquer sur le résultat dans le thread de liaison qui gère la requête. Nous vous recommandons plutôt de stocker la requête dans une file d'attente de requêtes et d'utiliser un thread de gestionnaire distinct pour gérer les requêtes de manière asynchrone. Pour en savoir plus, consultez la section Implémentation de référence.

Figure 1 : Processus asynchrone.

Parcelables volumineux

Toutes les structures nommées XXXs, telles que VehiclePropConfigs, SetValueRequests et VehiclePropValues, sont appelées LargeParcelable (ou StableLargeParcelable). Chacune représente une liste de valeurs utilisées pour transmettre de grandes données qui peuvent dépasser les limites du liaisonneur (4 ko dans l'implémentation de la bibliothèque LargeParcelable) au-delà des limites du liaisonneur. Chacune d'elles a une définition de structure similaire, qui contient les champs suivants.

Conseils Description
payloads Liste de valeurs lorsque la taille de la valeur correspond à une limite de mémoire du liaisonneur ou liste vide.
sharedMemoryFd Descripteur de fichier nullable pointant vers un fichier de mémoire partagée qui stocke les charges utiles sérialisées si la liste de valeurs est trop longue.

Par exemple, VehiclePropConfigs est défini comme suit:

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 contient des charges utiles non vides ou un sharedMemoryFd non nul.

  • Si payloads n'est pas vide, il stocke une liste des données réelles, qui est la configuration de la propriété.
  • Si sharedMemoryFd n'est pas nul, il contient un fichier de mémoire partagée, qui stocke la structure sérialisée de VehiclePropConfigs. La structure utilise la fonction writeToParcel pour sérialiser un parcel.

En tant que client Java pour VHAL, Car Service gère la sérialisation et la désérialisation pour LargeParcelable. Pour les implémentations VHAL et les clients natifs, un LargeParcelable doit être sérialisé et désérialisé avec la bibliothèque LargeParcelable ou une classe wrapper utile pour la bibliothèque dans ParcelableUtils.h.

Par exemple, un client natif analysant les requêtes pour getValues reçues d'un liant est le suivant:

// '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.
}

Vous trouverez ci-dessous un exemple d'implémentation de VHAL qui envoie des résultats pour getValues via le liaisonneur:

std::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}