HIDL est construit autour des interfaces, un type abstrait utilisé dans les domaines orientés objet pour définir des comportements. Chaque interface fait partie d'un package.
Packages
Les noms de packages peuvent avoir des sous-niveaux tels que package.subpackage
. La
Le répertoire racine des packages HIDL publiés est hardware/interfaces
ou vendor/vendorName
(par exemple, vendor/google
pour Pixel
appareils). Le nom du package forme un ou plusieurs sous-répertoires sous la racine
directory; tous les fichiers qui définissent un package
se trouvent dans le même répertoire. Par exemple :
package android.hardware.example.extension.light@2.0
est introuvable
moins de hardware/interfaces/example/extension/light/2.0
.
Le tableau suivant répertorie les préfixes et les emplacements des packages:
Préfixe du package | Position | Types d'interface |
---|---|---|
android.hardware.* |
hardware/interfaces/* |
HAL |
android.frameworks.* |
frameworks/hardware/interfaces/* |
cadres/ associés |
android.system.* |
system/hardware/interfaces/* |
au système/ |
android.hidl.* |
system/libhidl/transport/* |
core |
Le répertoire du package contient des fichiers portant l'extension .hal
. Toutes les
doit contenir une instruction package
nommant le package et
version dont fait partie le fichier. Le fichier types.hal
, s'il est présent,
non pas définir une interface, mais plutôt des types de données accessibles à tous
dans le package.
Définition de l'interface
Hormis types.hal
, tous les autres fichiers .hal
définissent
une interface. Une interface est généralement définie comme suit:
interface IBar extends IFoo { // IFoo is another interface // embedded types struct MyStruct {/*...*/}; // interface methods create(int32_t id) generates (MyStruct s); close(); };
Une interface sans déclaration extends
explicite implicitement
s'étend à partir de android.hidl.base@1.0::IBase
(comme
java.lang.Object
en Java.) L'interface IBase, implicitement
importé, déclare plusieurs méthodes réservées qui ne doivent pas et ne peuvent pas être
soit redéclarée dans des interfaces définies par l'utilisateur, soit utilisée autrement. Ces méthodes
incluent:
ping
interfaceChain
interfaceDescriptor
notifySyspropsChanged
linkToDeath
unlinkToDeath
setHALInstrumentation
getDebugInfo
debug
getHashChain
Processus d'importation
L'instruction import
est un mécanisme HIDL permettant d'accéder au package
interfaces et types
dans un autre package. Une instruction import
s'applique à deux entités:
- L'entité d'importation, qui peut être un package ou une de commande
- Entité importée, qui peut être un package ou une de commande
L'entité d'importation est déterminée par l'emplacement
import
. Lorsque l'instruction se trouve dans le
types.hal
: les éléments importés sont visibles par l'ensemble du package.
il s'agit d'une importation au niveau du package. Lorsque l'instruction se trouve à l'intérieur d'un
fichier d'interface, l'entité d'importation est l'interface elle-même. ceci est un
au niveau de l'interface.
L'entité importée est déterminée par la valeur située après import
mot clé. La valeur ne doit pas nécessairement être un nom complet. si un composant est
omis, il est automatiquement rempli avec les informations du package actuel.
Pour les valeurs complètes, les cas d'importation suivants sont acceptés:
- Importations de packages entiers. Si la valeur est un nom de package et un (syntaxe décrite ci-dessous), l'intégralité du package est importée dans la importation de l'entité.
- Importations partielles : Si la valeur est:
<ph type="x-smartling-placeholder">
- </ph>
- Une interface, le
types.hal
du package et cette interface sont importées dans l'entité d'importation. - Un UDT défini dans
types.hal
, seul cet UDT est importé dans L'entité à l'origine de l'importation (les autres types danstypes.hal
ne sont pas importés).
- Une interface, le
- Importations de types uniquement. Si la valeur utilise la syntaxe d'une
l'importation partielle décrite ci-dessus, mais avec le mot clé
types
à la place d'un nom d'interface, seuls les UDT danstypes.hal
de l'instance package sont importés.
L'entité importée a accès à une combinaison des éléments suivants:
- Les UDT communs du package importé définis dans
types.hal
- Les interfaces du package importé (pour une importation de package entier) ou les paramètres (pour une importation partielle) dans le but de les appeler, de transmettre et/ou en hérite.
L'instruction d'importation utilise la syntaxe du nom de type complet pour fournir le Nom et version du package ou de l'interface en cours d'importation:
import android.hardware.nfc@1.0; // import a whole package import android.hardware.example@1.0::IQuux; // import an interface and types.hal import android.hardware.example@1.0::types; // import just types.hal
Héritage de l'interface
Une interface peut être une extension d'une interface définie précédemment. Il existe trois types d'extensions:
- Interface peut ajouter des fonctionnalités à une autre, en incorporant son API ne sont pas modifiées.
- Le package peut ajouter des fonctionnalités à un autre en incorporant son API ne sont pas modifiées.
- L'interface peut importer des types à partir d'un package ou d'une interface spécifique.
Une interface ne peut étendre qu'une seule autre interface (sans héritage multiple).
Chaque interface d'un package ayant un numéro de version mineure non nulle doit étendre une
dans la version précédente du package. Par exemple, si une interface
IBar
de la version 4.0 du package derivative
est basé sur
(étend) une interface IFoo
dans la version 1.2 du package
original
, et la version 1.3 du package original
est
créé, IBar
version 4.1 ne peut pas étendre la version 1.3 de
IFoo
À la place, la version 4.1 de IBar
doit étendre
La version 4.0 de IBar
, qui est liée à la version 1.2 de IFoo
.
La version 5.0 de IBar
pourrait étendre la version 1.3 de IFoo
, si
comme vous le souhaitez.
Les extensions d'interface n'impliquent pas de dépendance à une bibliothèque ni d'inclusion entre HAL. dans le code généré : ils importent simplement la structure des données et leur méthode au niveau du HIDL. Chaque méthode d'une HAL doit être implémentée CARL.
Extensions de fournisseur
Dans certains cas, les extensions de fournisseur sont implémentées en tant que sous-classes du qui représente l'interface principale qu'ils étendent. Le même objet est enregistré sous le nom et la version HAL de base, et sous le sous-réseau (vendor) Nom et version HAL.
Gestion des versions
Les packages ont des versions gérées et les interfaces possèdent la version de leur package. Les versions sont exprimées sous la forme de deux entiers : major.minor.
- Les versions majeures ne sont pas rétrocompatibles. Incrémentation le numéro de version majeure réinitialise le numéro de version mineure à 0.
- Les versions mineures sont rétrocompatibles. En augmentant la valeur indique que la version la plus récente est entièrement rétrocompatible avec le version précédente. Vous pouvez ajouter de nouvelles structures et méthodes de données, mais aucune structure existante les structures de données ou les signatures de méthode peuvent être modifiées.
Plusieurs versions majeures ou mineures d'une HAL peuvent être présentes sur un appareil. simultanément. Cependant, une version mineure est préférable à une version majeure. car le code client qui fonctionne avec l'interface d'une version mineure précédente fonctionne également avec les versions ultérieures mineures de cette même interface. Pour plus pour en savoir plus sur la gestion des versions et les extensions de fournisseur, consultez Gestion des versions HIDL.
Résumé de la mise en page de l'interface
Cette section résume comment gérer un package d'interface HIDL (tel que
hardware/interfaces
) et regroupe les informations présentées
tout au long de
la section HIDL. Avant de lire cet article, assurez-vous de bien connaître
la gestion des versions HIDL,
le hachage avec
hidl-gen, les détails de l'utilisation avec
HIDL en général et définitions suivantes:
Terme | Définition |
---|---|
interface binaire d'application (ABI) | Interface de programmation d'application et liaisons binaires requises. |
nom complet (fqName) | Nom permettant de distinguer un type d'hidl. Exemple:
android.hardware.foo@1.0::IFoo |
colis | Package contenant une interface et des types HIDL. Exemple:
android.hardware.foo@1.0 |
racine du package | Package racine contenant les interfaces HIDL. Exemple: interface HIDL
android.hardware se trouve dans la racine du package
android.hardware.foo@1.0 |
chemin d'accès racine du package | Emplacement dans l'arborescence source Android où est mappée la racine d'un package. |
Pour obtenir plus de définitions, consultez HIDL Terminologie.
Chaque fichier peut être trouvé à partir du mappage de la racine du package et son nom complet ;
Les racines du package sont spécifiées sur hidl-gen
en tant qu'argument
-r android.hardware:hardware/interfaces
Par exemple, si le
le package est vendor.awesome.foo@1.0::IFoo
et hidl-gen
est envoyée le -r vendor.awesome:some/device/independent/path/interfaces
,
le fichier d'interface
doit se trouver dans
$ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal
En pratique, il est recommandé pour un fournisseur ou un OEM nommé awesome
.
de placer leurs interfaces standards dans vendor.awesome
. Après un colis
chemin d'accès a été sélectionné, il ne doit pas être modifié, car il est intégré à l'ABI de
l'interface.
Le mappage du chemin d'accès au package doit être unique
Par exemple, si vous avez -rsome.package:$PATH_A
et
-rsome.package:$PATH_B
, $PATH_A
doit être égal à
$PATH_B
pour un répertoire d'interface cohérent (cela rend également
interfaces de gestion des versions
plus facilement).
La racine du package doit comporter un fichier de gestion des versions
Si vous créez un chemin d'accès au package tel que
-r vendor.awesome:vendor/awesome/interfaces
, vous devez également
créer le fichier
$ANDROID_BUILD_TOP/vendor/awesome/interfaces/current.txt
, qui
doit contenir les hachages des interfaces créées à l'aide de l'option -Lhash
dans
hidl-gen
(ce sujet est abordé en détail dans
Hachage avec
hidl-gen).
Les interfaces sont indépendantes de l'appareil zones géographiques
En pratique, nous vous recommandons de partager les interfaces entre les branches. Ce permet de réutiliser le code le plus souvent possible et de le tester au maximum sur différentes appareils et cas d'utilisation.