HIDL nécessite que chaque interface écrite en HIDL possède une version gérée. Après une opération HAL l'interface est publiée, elle est bloquée et toute modification supplémentaire doit être apportée nouvelle version de cette interface. Bien qu'une interface publiée donnée ne puisse pas être modifié, il peut être étendu par une autre interface.
Structure du code HIDL
Le code HIDL est organisé en blocs définis par l'utilisateur types, interfaces et packages:
- Types définis par l'utilisateur (UDT). HIDL permet d'accéder à un ensemble types de données primitifs qui peuvent être utilisés pour composer des types plus complexes via les structures, les unions et les énumérations. Les UDT sont transmises aux méthodes interfaces et peuvent être définies au niveau d'un package (commun à toutes interfaces) ou localement à une interface.
- Interfaces : En tant que composant de base de HIDL, une interface se compose d'UDT et de déclarations de méthode. Les interfaces peuvent aussi hériter une autre interface.
- Packages : Organise les interfaces HIDL associées et les données
sur lesquels elles opèrent. Un package est identifié par
un nom et une version et
comprend les éléments suivants:
<ph type="x-smartling-placeholder">
- </ph>
- Fichier de définition du type de données appelé
types.hal
. - Aucune, une ou plusieurs interfaces, chacune dans son propre fichier
.hal
.
- Fichier de définition du type de données appelé
Le fichier de définition de type de données types.hal
ne contient que des UDT
les UDT au niveau du package sont conservés dans un seul fichier. Représentations dans la cible
sont disponibles pour toutes les interfaces du package.
Philosophie de gestion des versions
Un package HIDL (tel que android.hardware.nfc
), après avoir été
publiée pour une version donnée (par exemple, 1.0
) est immuable. cette
ne peut pas être modifiée. Les modifications des interfaces
du package ou de toute
les modifications de ses UDT ne peuvent avoir lieu que dans un autre package.
Dans HIDL, la gestion des versions s'applique au niveau du package, pas au niveau de l'interface, et toutes les interfaces et tous les UDT d'un package partagent la même version. Colis d'après les versions sémantiques gestion des versions sans les composants de niveau de correctif et de métadonnées de compilation. Dans un package donné, une augmentation de version mineure implique la nouvelle version de le package est rétrocompatible avec l'ancien paquet et un système principal version signifie que la nouvelle version du package n'est pas rétrocompatible avec l'ancien package.
D'un point de vue conceptuel, un package peut être associé à un autre package de plusieurs manières:
- Pas du tout.
- Extensibilité rétrocompatible au niveau du package. Ce
se produit pour les nouvelles versions supérieures d'une version mineure (révision par incréments suivante) d'un package ;
le nouveau package a le même nom et la même version majeure que l'ancien, mais une
version mineure supérieure. D'un point de vue fonctionnel, le nouveau package est un sur-ensemble de l'ancien
"package", c'est-à-dire:
<ph type="x-smartling-placeholder">
- </ph>
- Les interfaces de niveau supérieur du package parent
sont présentes dans le nouveau package,
bien que les interfaces puissent avoir de nouvelles méthodes, de nouveaux UDT locaux d'interface (les
l'extension au niveau de l'interface décrite ci-dessous) et de nouveaux modèles UDT dans
types.hal
- De nouvelles interfaces peuvent également être ajoutées au nouveau package.
- Tous les types de données du package parent sont présents dans le nouveau package et peuvent être gérés par les méthodes (éventuellement réimplémentées) de l'ancien package.
- De nouveaux types de données peuvent également être ajoutés pour être utilisés par l'une ou l'autre des nouvelles méthodes de mise à jour. via des interfaces existantes, ou par de nouvelles interfaces.
- Les interfaces de niveau supérieur du package parent
sont présentes dans le nouveau package,
bien que les interfaces puissent avoir de nouvelles méthodes, de nouveaux UDT locaux d'interface (les
l'extension au niveau de l'interface décrite ci-dessous) et de nouveaux modèles UDT dans
- Extensibilité rétrocompatible au niveau de l'interface. Les nouvelles
le package d'origine peut également étendre le package d'origine en se basant sur des
des interfaces qui fournissent simplement des
fonctionnalités supplémentaires, et non l’interface de base.
À cette fin, il peut être souhaitable d'effectuer les opérations suivantes:
<ph type="x-smartling-placeholder">
- </ph>
- Les interfaces du nouveau package ont besoin de recourir aux types de données de l'ancien. d'un package.
- Les interfaces du nouveau package peuvent étendre les interfaces d'un ou de plusieurs anciens packages packages.
- Prolonger l'incompatibilité ascendante d'origine Il s'agit d'un de la mise à niveau vers la version majeure du package et il n'est pas nécessaire qu'il y ait de corrélation entre les deux. Si tel est le cas, il peut être exprimé à l'aide d'une combinaison de l'ancienne version du package et héritage d'un sous-ensemble de l'ancien package.
Structuration de l'interface
Pour une interface bien structurée, l'ajout de nouveaux types de fonctionnalités ne font pas partie de la conception d’origine devrait nécessiter une modification du HIDL de commande. À l'inverse, si vous pouvez ou prévoyez d'effectuer un changement des deux côtés L'interface qui introduit de nouvelles fonctionnalités sans modifier l'interface elle-même, alors l’interface n’est pas structurée.
Treble prend en charge les composants fournisseur et système compilés séparément dans lesquels le
vendor.img
sur un appareil et system.img
peut être
compilées séparément. Toutes les interactions entre vendor.img
et
Les system.img
doivent être définies explicitement et minutieusement afin de pouvoir
continuent à travailler pendant de nombreuses années. Cela inclut de nombreuses surfaces d'API, mais un
surface est le mécanisme d'IPC utilisé par HIDL pour la communication inter-processus sur le
Limite system.img
/vendor.img
.
Conditions requises
Toutes les données transmises via HIDL doivent être définies explicitement. Pour vous assurer qu'une et le client peut continuer à fonctionner ensemble, même lorsqu'il est compilé séparément ou développées indépendamment, les données doivent respecter les configuration requise:
- Peut être décrit directement en HIDL (à l'aide d'énumérations structs, etc.) avec noms sémantiques et leur signification.
- Peut être décrit par une norme publique telle que ISO/IEC 7816.
- Peut être décrit par une norme matérielle ou une disposition physique du matériel.
- Il peut s'agir de données opaques (telles que des clés publiques, des identifiants, etc.) si nécessaire.
Si des données opaques sont utilisées, elles ne doivent être lues que par un seul côté du HIDL
de commande. Par exemple, si le code vendor.img
donne à un composant sur le
system.img
un message de chaîne ou vec<uint8_t>
données, ces données ne peuvent pas être analysées par la system.img
elle-même. il peut
ne seront renvoyés qu'à vendor.img
pour interpréter. Quand
en transmettant une valeur de vendor.img
au code fournisseur sur
system.img
ou à un autre appareil, le format des données et la façon dont elles
doit être décrite avec précision et fait toujours partie du
de commande.
Consignes
Vous devez être en mesure d'écrire une implémentation ou un client d'une HAL en utilisant uniquement les fichiers .hal (vous n'avez pas besoin de consulter la source Android standards). Nous vous recommandons de spécifier le comportement exact requis. Les déclarations telles que tels que "une implémentation pourrait faire A ou B" encourager les implémentations à devenir en lien avec les clients avec lesquels ils sont développés.
Mise en page du code HIDL
HIDL inclut les packages de base et les packages fournisseurs.
Les interfaces HIDL principales sont celles spécifiées par Google. Les packages auxquels ils appartiennent
commencent par android.hardware.
et sont nommés par sous-système,
potentiellement avec des niveaux
imbriqués de nommage. Par exemple, le package NFC est nommé
android.hardware.nfc
et le package appareil photo est
android.hardware.camera
En général, un package de base porte le nom
android.hardware.
[name1
].[name2
]....
Les packages HIDL ont une version en plus de leur nom. Par exemple, le package
android.hardware.camera
est peut-être en version 3.4
. c'est
important, car la version d'un package affecte son emplacement dans l'arborescence source.
Tous les packages de base sont placés sous hardware/interfaces/
dans
du système de compilation. Le package
android.hardware.
[name1
].[name2
]...
à la version $m.$n
est sous
hardware/interfaces/name1/name2/
.../$m.$n/
; package
La version 3.4
de android.hardware.camera
se trouve dans le répertoire
hardware/interfaces/camera/3.4/.
Un mappage codé en dur existe
entre le préfixe de package android.hardware.
et le chemin d'accès
hardware/interfaces/
Les packages autres que les packages principaux sont ceux produits par le fournisseur SoC ou l'ODM. La
pour les packages non principaux est vendor.$(VENDOR).hardware.
, où
$(VENDOR)
fait référence à un fournisseur de SoC ou à un OEM/ODM. Cela correspond au chemin
vendor/$(VENDOR)/interfaces
dans l'arborescence (ce mappage est également
codées en dur).
Noms complets définis par l'utilisateur
Dans HIDL, chaque UDT a un nom
complet composé du nom UDT,
le nom du package dans lequel l'UDT est défini et la version du package. La
un nom complet n'est utilisé que lorsque des instances du type sont déclarées et
et non là où le type lui-même est défini. Par exemple, supposons que le package
La version 1.0
de android.hardware.nfc,
définit un struct
nommée NfcData
. Sur le site de la déclaration (que ce soit
types.hal
ou dans une déclaration d'interface), la déclaration
indique simplement:
struct NfcData { vec<uint8_t> data; };
Lors de la déclaration d'une instance de ce type (que ce soit dans une structure de données ou comme paramètre de méthode), utilisez le nom de type complet:
android.hardware.nfc@1.0::NfcData
La syntaxe générale est
PACKAGE@VERSION::UDT
, où:
PACKAGE
est le nom d'un package HIDL, séparé par un point (par exemple,android.hardware.nfc
).VERSION
est la version majeure.minor-version séparée par un point. format du package (par exemple,1.0
).UDT
est le nom d'un UDT HIDL, séparé par un point. Étant donné que HIDL prend en charge les UDT imbriquées, les interfaces HIDL peuvent contenir des UDT (un type de déclaration imbriquée), des points sont utilisés pour accéder aux noms.
Par exemple, si la déclaration imbriquée suivante a été définie dans le fichier commun
fichier de types dans la version android.hardware.example
du package
1.0
:
// types.hal package android.hardware.example@1.0; struct Foo { struct Bar { // … }; Bar cheers; };
Le nom complet de Bar
est
android.hardware.example@1.0::Foo.Bar
Si, en plus d’être dans
du package ci-dessus, la déclaration imbriquée se trouvait dans une interface appelée
IQuux
:
// IQuux.hal package android.hardware.example@1.0; interface IQuux { struct Foo { struct Bar { // … }; Bar cheers; }; doSomething(Foo f) generates (Foo.Bar fb); };
Le nom complet de Bar
est
android.hardware.example@1.0::IQuux.Foo.Bar
Dans les deux cas, Bar
ne peut être désigné que par Bar
dans le champ d'application de la déclaration de Foo
. Sur le colis ou
au niveau de l'interface, vous devez faire référence à Bar
via Foo
:
Foo.Bar
, comme dans la déclaration de la méthode doSomething
ci-dessus. Vous pouvez également déclarer la méthode de manière plus détaillée comme suit:
// IQuux.hal doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);
Valeurs d'énumération complètes
Si un UDT est de type enum, alors chaque valeur de ce type possède un
nom complet qui commence par le nom complet du type d'énumération
suivi du signe deux-points, puis du nom de la valeur d'énumération. Par exemple :
suppose la version 1.0
du package android.hardware.nfc,
définit un type d'énumération NfcStatus
:
enum NfcStatus { STATUS_OK, STATUS_FAILED };
Lorsque vous faites référence à STATUS_OK
, le nom complet est le suivant:
android.hardware.nfc@1.0::NfcStatus:STATUS_OK
La syntaxe générale est
PACKAGE@VERSION::UDT:VALUE
,
où:
PACKAGE@VERSION::UDT
est le exactement le même nom complet pour le type d'énumération.VALUE
est le nom de la valeur.
Règles d'inférence automatique
Il n'est pas nécessaire de spécifier un nom UDT complet. Un nom UDT peut omettez en toute sécurité les éléments suivants:
- Le package (par exemple,
@1.0::IFoo.Type
- Package et version (par exemple,
IFoo.Type
HIDL tente de compléter le nom à l'aide de règles d'interférence automatique (règle inférieure le chiffre correspond au niveau de priorité le plus élevé).
Règle 1
Si aucun package et aucune version ne sont fournis, une tentative de recherche du nom local est effectuée. Exemple :
interface Nfc { typedef string NfcErrorMessage; send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m); };
NfcErrorMessage
est recherché localement et typedef
au-dessus de celui-ci est trouvé. NfcData
est également recherché localement, mais comme c'est le cas
non définies localement, les règles 2 et 3 sont utilisées. @1.0::NfcStatus
fournit une version, la règle 1 ne s'applique donc pas.
Règle 2
Si la règle 1 échoue et qu'un composant du nom complet est manquant
(package, version ou package et version), le composant est rempli automatiquement avec
des informations du
package actuel. Le compilateur HIDL recherche ensuite dans
fichier actuel (et toutes les importations) pour trouver le nom complet saisi automatiquement.
À l'aide de l'exemple ci-dessus, supposons que la déclaration ExtendedNfcData
a été faite dans le même package (android.hardware.nfc
) et
(1.0
) en tant que NfcData
, comme suit:
struct ExtendedNfcData { NfcData base; // … additional members };
Le compilateur HIDL renseigne le nom du package et le nom de la version à partir du
le package actuel pour produire le nom UDT complet
android.hardware.nfc@1.0::NfcData
Comme le nom existe dans le
le package actuel (en supposant qu'il est importé correctement), il est utilisé pour
la déclaration.
Un nom du package actuel n'est importé que si l'un des éléments suivants est true:
- Il est importé explicitement avec une instruction
import
. - Il est défini dans
types.hal
dans le package actuel.
La même procédure est suivie si NfcData
a été qualifié uniquement par
le numéro de version:
struct ExtendedNfcData { // autofill the current package name (android.hardware.nfc) @1.0::NfcData base; // … additional members };
Règle 3
Si la règle 2 ne produit pas de correspondance (l'UDT n'est pas défini dans le code
package), le compilateur HIDL recherche une correspondance dans tous les packages importés.
À l'aide de l'exemple ci-dessus, supposons que ExtendedNfcData
est déclaré dans
la version 1.1
du package android.hardware.nfc
,
1.1
importe 1.0
comme il se doit (voir
Extensions au niveau du package), et la définition
spécifie uniquement le nom UDT:
struct ExtendedNfcData { NfcData base; // … additional members };
Le compilateur recherche n'importe quel UDT nommé NfcData
et en trouve un dans
android.hardware.nfc
en version 1.0
, ce qui entraîne une
UDT complet de android.hardware.nfc@1.0::NfcData
. Si plus
plusieurs correspondances sont trouvées pour un UDT partiellement qualifié, le compilateur HIDL
génère une erreur.
Exemple
À l'aide de la règle 2, un type importé défini dans le package actuel est privilégié un type importé d'un autre package:
// hardware/interfaces/foo/1.0/types.hal package android.hardware.foo@1.0; struct S {}; // hardware/interfaces/foo/1.0/IFooCallback.hal package android.hardware.foo@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/types.hal package android.hardware.bar@1.0; typedef string S; // hardware/interfaces/bar/1.0/IFooCallback.hal package android.hardware.bar@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/IBar.hal package android.hardware.bar@1.0; import android.hardware.foo@1.0; interface IBar { baz1(S s); // android.hardware.bar@1.0::S baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback };
S
est interpolé en tant queandroid.hardware.bar@1.0::S
, se trouve dansbar/1.0/types.hal
(cartypes.hal
est automatiquement importées).IFooCallback
est interpolé en tant queandroid.hardware.bar@1.0::IFooCallback
à l'aide de la règle 2, est introuvable, carbar/1.0/IFooCallback.hal
n'a pas été importé automatiquement (commetypes.hal
). Ainsi, la règle 3 le résout enandroid.hardware.foo@1.0::IFooCallback
, qui est importé viaimport android.hardware.foo@1.0;
).
types.hal
Chaque package HIDL contient un fichier types.hal
contenant des UDT
qui sont partagés entre toutes les interfaces
participant à ce package. Types de HIDL
sont toujours publiques ; qu'un UDT soit déclaré ou non
types.hal
ou dans une déclaration d'interface, ces types sont
accessibles en dehors du champ
d'application où ils sont définis. types.hal
n'est pas destiné à décrire l'API publique d'un package, mais plutôt à héberger des UDT
utilisé par toutes les interfaces
du package. En raison de la nature du HIDL, tous les UDT
font partie de l'interface.
types.hal
se compose d'UDT et d'instructions import
.
Étant donné que types.hal
est mis à la disposition de toutes les interfaces de
(il s'agit d'une importation implicite), ces instructions import
sont
au niveau du package par définition. Les UDT dans types.hal
peuvent également intégrer
UDT et interfaces ainsi importés.
Par exemple, pour un IFoo.hal
:
package android.hardware.foo@1.0; // whole package import import android.hardware.bar@1.0; // types only import import android.hardware.baz@1.0::types; // partial imports import android.hardware.qux@1.0::IQux.Quux; // partial imports import android.hardware.quuz@1.0::Quuz;
Les éléments suivants sont importés:
android.hidl.base@1.0::IBase
(implicitement)android.hardware.foo@1.0::types
(implicitement)- Tous les éléments de
android.hardware.bar@1.0
(y compris tous interfaces et sestypes.hal
) types.hal
deandroid.hardware.baz@1.0::types
(les interfaces deandroid.hardware.baz@1.0
ne sont pas importées)IQux.hal
ettypes.hal
deandroid.hardware.qux@1.0
Quuz
à partir deandroid.hardware.quuz@1.0
(en supposantQuuz
est défini danstypes.hal
, l'intégralitétypes.hal
fichier est analysé, mais les types autres queQuuz
ne sont pas importées).
Gestion des versions au niveau de l'interface
Chaque interface d'un package se trouve dans son propre fichier. Le package
auquel appartient l'interface est déclarée en haut de l'interface à l'aide de la méthode
package
. Après la déclaration du package, zéro ou plus
les importations au niveau de l'interface (partielles ou complètes) peuvent être répertoriées. Exemple :
package android.hardware.nfc@1.0;
Dans HIDL, les interfaces peuvent hériter d'autres interfaces à l'aide du
extends
mot clé. Pour qu'une interface étende une autre interface,
doit y avoir accès via une instruction import
. Le nom du
l'interface étendue (l'interface de base) respecte les règles pour type-name
d'éligibilité expliquée ci-dessus. Une interface ne peut hériter que d'une seule interface.
HIDL n'est pas compatible avec l'héritage multiple.
Les exemples de gestion des versions "uprev" ci-dessous utilisent le package suivant:
// types.hal package android.hardware.example@1.0 struct Foo { struct Bar { vec<uint32_t> val; }; }; // IQuux.hal package android.hardware.example@1.0 interface IQuux { fromFooToBar(Foo f) generates (Foo.Bar b); }
Règles d'augmentation
Pour définir un package package@major.minor
: A ou l'ensemble de B
doit être vraie:
Règle A | "Est une version mineure de début" : toutes les versions mineures précédentes,
package@major.0 , package@major.1 , etc.
package@major.(minor-1) ne doit pas être défini.
|
---|
Règle B | Toutes les affirmations suivantes sont vraies:
|
---|
En raison de la règle A:
- Le package peut commencer par n'importe quel numéro de version mineure (par exemple,
android.hardware.biometrics.fingerprint
commence à@2.1
). - L'exigence "
android.hardware.foo@1.0
n'est pas définie" signifie le répertoirehardware/interfaces/foo/1.0
ne devrait même pas exister.
Cependant, la règle A n'affecte pas un package portant le même nom, mais ayant une paire valeur/clé
une autre version majeure (par exemple,
android.hardware.camera.device
a à la fois @1.0
et
@3.2
défini @3.2
n'a pas besoin d'interagir avec
@1.0
.) Par conséquent, @3.2::IExtFoo
peut étendre
@1.0::IFoo
Si le nom du package est différent,
package@major.minor::IBar
peut s'étendre à partir d'une interface avec un
un autre nom (par exemple, android.hardware.bar@1.0::IBar
peut
étendre android.hardware.baz@2.2::IBaz
). Si une interface ne dispose pas
déclarer explicitement un super-type avec le mot clé extend
,
étend android.hidl.base@1.0::IBase
(sauf IBase
)
lui-même).
Les sections B.2 et B.3 doivent être suivies en même temps. Par exemple, même si
android.hardware.foo@1.1::IFoo
extension
android.hardware.foo@1.0::IFoo
pour valider la règle B.2, si une
android.hardware.foo@1.1::IExtBar
extension
android.hardware.foo@1.0::IBar
, ce montant n'est toujours pas valide.
Interfaces Uprev
Pour augmenter la valeur de android.hardware.example@1.0
(défini ci-dessus) à
@1.1
:
// types.hal package android.hardware.example@1.1; import android.hardware.example@1.0; // IQuux.hal package android.hardware.example@1.1 interface IQuux extends @1.0::IQuux { fromBarToFoo(Foo.Bar b) generates (Foo f); }
Il s'agit d'un import
au niveau du package de la version 1.0
de
android.hardware.example
dans types.hal
. Bien qu'il ne soit pas nouveau
Les UDT sont ajoutées dans la version 1.1
du package. Les références aux UDT dans
la version 1.0
sont encore nécessaires, d'où l'importation au niveau du package.
dans le pays suivant : types.hal
. (Le même effet aurait pu être obtenu avec une
importation au niveau de l'interface dans IQuux.hal
.)
Dans extends @1.0::IQuux
, dans la déclaration de
IQuux
, nous avons spécifié la version de IQuux
actuellement en cours
héritée (la clarification est obligatoire, car IQuux
est utilisé pour
déclarer une interface et hériter d'une interface). Étant donné que les déclarations sont
simplement les noms qui héritent de tous les attributs de package et de version sur le site du
la liste doit être clarifiée dans le nom de l'interface de base ; nous
aurait également pu utiliser
l'UDT complet, mais cela aurait été
redondants.
La nouvelle interface IQuux
ne redéclare pas la méthode
fromFooToBar()
hérite de @1.0::IQuux
; il suffit
affiche la nouvelle méthode et ajoute fromBarToFoo()
. En HIDL, les valeurs héritées
ne peuvent pas être déclarées à nouveau dans les interfaces enfants. Par conséquent,
l'interface IQuux
ne peut pas déclarer le fromFooToBar()
explicitement.
Conventions Uprev
Il arrive que le nom de l'interface d'extension doive être renommé. Nous vous recommandons que les extensions, les structures et les unions d'énumération portent le même nom que ce qu'ils étendent ; sauf s'ils sont suffisamment différents pour justifier un nouveau nom. Exemples :
// in parent hal file enum Brightness : uint32_t { NONE, WHITE }; // in child hal file extending the existing set with additional similar values enum Brightness : @1.0::Brightness { AUTOMATIC }; // extending the existing set with values that require a new, more descriptive name: enum Color : @1.0::Brightness { HW_GREEN, RAINBOW };
Si une méthode peut avoir un nouveau nom sémantique (par exemple,
fooWithLocation
), il est préférable d'utiliser cette option. Sinon, il doit s'agir
nommé de la même manière que
ce qu'il étend. Par exemple, la méthode
foo_1_1
dans @1.1::IFoo
peut remplacer la fonctionnalité
de la méthode foo
dans @1.0::IFoo
, s'il n'y a pas de meilleure
nom alternatif.
Gestion des versions au niveau du package
La gestion des versions HIDL s'effectue au niveau du package. après la publication d'un package, est immuable (son ensemble d'interfaces et d'UDT ne peut pas être modifié). Les packages peuvent se rapportent les uns aux autres de plusieurs manières, qui peuvent toutes s'exprimer via un combinaison de l'héritage au niveau de l'interface et de la création d'UDT par composition.
Cependant, un type de relation est strictement défini et doit être appliqué: Héritage rétrocompatible au niveau du package. Dans ce scénario, le Le package parent correspond au package hérité et Le package child est celui qui étend le parent. Au niveau du package Les règles d'héritage rétrocompatibles sont les suivantes:
- Toutes les interfaces de niveau supérieur du package parent sont héritées par les interfaces dans le package enfant.
- De nouvelles interfaces peuvent également être ajoutées au nouveau package (aucune restriction les relations avec d'autres interfaces dans d'autres packages).
- De nouveaux types de données peuvent également être ajoutés pour être utilisés par l'une ou l'autre des nouvelles méthodes de mise à jour. via des interfaces existantes, ou par de nouvelles interfaces.
Ces règles peuvent être implémentées à l'aide de l'héritage au niveau de l'interface HIDL et de l'UDT la composition, mais ils nécessitent des connaissances de niveau méta-niveau pour connaître ces relations constituent une extension de package rétrocompatible. Ces connaissances sont déduites comme suit:
Si un package répond à cette exigence, hidl-gen
applique
des règles de rétrocompatibilité.