Fichiers manifestes

Un objet VINTF agrège les données des fichiers fichier manifeste de l'appareil et fichier manifeste du framework (XML). Les deux fichiers manifestes partagent un format, bien que tous les éléments ne s'appliquent pas aux deux (pour en savoir plus sur le schéma, consultez la section Schéma de fichier manifeste).

Fichier manifeste de l'appareil

Le fichier manifeste de l'appareil (fourni par l'appareil) se compose du fichier manifeste du fournisseur et du fichier manifeste de l'OEM.

  • Le fichier manifeste du fournisseur spécifie les HAL, les versions de règles SELinux, etc. communs à un SoC. Il est recommandé de le placer dans l'arborescence source Android à l'emplacement device/VENDOR/DEVICE/manifest.xml, mais plusieurs fichiers de fragments peuvent être utilisés. Pour en savoir plus, consultez Fragments de fichier manifeste et Générer un message direct à partir de fragments.
  • Le fichier manifeste ODM liste les HAL spécifiques au produit dans la partition ODM. L'objet VINTF charge le fichier manifeste ODM dans l'ordre suivant :
    1. Si SKU est défini (où SKU est la valeur de la propriété ro.boot.product.hardware.sku), alors : /odm/etc/vintf/manifest_SKU.xml
    2. /odm/etc/vintf/manifest.xml
    3. Si SKU est défini, /odm/etc/manifest_SKU.xml
    4. /odm/etc/manifest.xml
  • Le fichier manifeste du fournisseur liste les HAL spécifiques au produit dans la partition du fournisseur. L'objet VINTF charge le fichier manifeste du fournisseur dans l'ordre suivant :
    1. Si SKU est défini (où SKU est la valeur de la propriété ro.boot.product.vendor.sku), alors : /vendor/etc/vintf/manifest_SKU.xml
    2. /vendor/etc/vintf/manifest.xml
  • L'objet VINTF charge le fichier manifeste de l'appareil dans l'ordre suivant :
    1. Si le fichier manifeste du fournisseur existe, combinez les éléments suivants :
      1. Le fichier manifeste du fournisseur
      2. Fragments de fichier manifeste du fournisseur facultatifs
      3. Fichier manifeste ODM facultatif
      4. Fragments de fichier manifeste ODM facultatifs
    2. Sinon, si le fichier manifeste ODM existe, combinez-le avec les fragments de fichier manifeste ODM facultatifs.
    3. /vendor/manifest.xml (ancienne, sans fragments)
    4. Enfin, combinez les fragments de fichier manifeste de tous les APEX de fournisseurs. Les fragments de fichier manifeste sont chargés à partir du répertoire etc/vintf de chaque APEX (par exemple, /apex/<apex name>/etc/vintf).

    Gardez à l'esprit les points suivants :

    • Sur les anciens appareils, le fichier manifeste du fournisseur précédent et le fichier manifeste ODM sont utilisés. Le fichier manifeste ODM peut remplacer complètement le fichier manifeste du fournisseur précédent.
    • Sur les appareils lancés avec Android 9, le fichier manifeste ODM est combiné au fichier manifeste du fournisseur.
    • Lorsque vous combinez une liste de fichiers manifestes, les fichiers manifestes qui apparaissent plus tard dans la liste peuvent remplacer les balises des fichiers manifestes qui apparaissent plus tôt dans la liste, à condition que les balises du fichier manifeste ultérieur comportent l'attribut override="true". Par exemple, le fichier manifeste ODM peut remplacer certaines balises <hal> du fichier manifeste du fournisseur. Consultez la documentation de l'attribut override ci-dessous.

Cette configuration permet à plusieurs produits avec la même carte de partager la même image du fournisseur (qui fournit des HAL communs) tout en ayant des images ODM différentes (qui spécifient des HAL spécifiques au produit).

Voici un exemple de fichier manifeste du fournisseur.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="2.0" type="device" target-level="1">
    <hal>
        <name>android.hardware.camera</name>
        <transport>hwbinder</transport>
        <version>3.4</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>legacy/0</instance>
            <instance>proprietary/0</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <version>2.0</version>
        <interface>
            <name>INfc</name>
            <instance>nfc_nci</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
        <fqname>@2.0::INfc/default</fqname>
    </hal>
    <hal>
        <name>android.hardware.drm</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ICryptoFactory</name>
            <instance>default</instance>
        </interface>
        <interface>
            <name>IDrmFactory</name>
            <instance>default</instance>
        </interface>
        <fqname>@1.1::ICryptoFactory/clearkey</fqname>
        <fqname>@1.1::IDrmFactory/clearkey</fqname>
    </hal>
    <hal format="aidl">
        <name>android.hardware.light</name>
        <version>1</version>
        <fqname>ILights/default</fqname>
    </hal>
    <hal format="aidl">
        <name>android.hardware.power</name>
        <version>2</version>
        <interface>
            <name>IPower</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal format="native">
        <name>EGL</name>
        <version>1.1</version>
    </hal>
    <hal format="native">
        <name>GLES</name>
        <version>1.1</version>
        <version>2.0</version>
        <version>3.0</version>
    </hal>
    <sepolicy>
        <version>25.0</version>
    </sepolicy>
</manifest>

Voici un exemple de fichier manifeste ODM.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="device">
    <!-- camera 3.4 in vendor manifest is ignored -->
    <hal override="true">
        <name>android.hardware.camera</name>
        <transport>hwbinder</transport>
        <version>3.5</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>legacy/0</instance>
        </interface>
    </hal>
    <!-- NFC is declared to be disabled -->
    <hal override="true">
        <name>android.hardware.nfc</name>
        <transport>hwbinder</transport>
    </hal>
    <hal>
        <name>android.hardware.power</name>
        <transport>hwbinder</transport>
        <version>1.1</version>
        <interface>
            <name>IPower</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>

Voici un exemple de fichier manifeste d'appareil dans un package OTA.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="device" target-level="1">
    <!-- hals ommited -->
    <kernel version="4.4.176">
        <config>
            <key>CONFIG_ANDROID</key>
            <value>y</value>
        </config>
        <config>
            <key>CONFIG_ARM64</key>
            <value>y</value>
        </config>
    <!-- other configs ommited -->
    </kernel>
</manifest>

Pour en savoir plus, consultez la section Développement du fichier manifeste de l'appareil.

Fichier manifeste du framework

Le fichier manifeste du framework se compose du fichier manifeste du système, du fichier manifeste du produit et du fichier manifeste system_ext.

  • Le fichier manifeste système (fourni par Google) est généré manuellement et se trouve dans l'arborescence source Android à l'emplacement /system/libhidl/manifest.xml.
  • Le fichier manifeste du produit (fourni par l'appareil) liste les HAL gérés par les modules installés sur la partition du produit.
  • Le fichier manifeste system_ext (fourni par l'appareil) contient les éléments suivants :
    • HAL gérés par des modules installés sur la partition system_ext
    • Versions du VNDK ;
    • Version du SDK système.

Comme pour le fichier manifeste de l'appareil, vous pouvez utiliser plusieurs fichiers de fragments. Pour en savoir plus, consultez la section Fragments de fichier manifeste.

Voici un exemple de fichier manifeste de framework.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Comments, Legal notices, etc. here -->
<manifest version="1.0" type="framework">
    <hal>
        <name>android.hidl.allocator</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IAllocator</name>
            <instance>ashmem</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hidl.memory</name>
        <transport arch="32+64">passthrough</transport>
        <version>1.0</version>
        <interface>
            <name>IMapper</name>
            <instance>ashmem</instance>
        </interface>
    </hal>
    <hal>
        <name>android.hidl.manager</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IServiceManager</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal>
        <name>android.frameworks.sensorservice</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ISensorManager</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal max-level="5">
        <name>android.frameworks.schedulerservice</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>ISchedulingPolicyService</name>
            <instance>default</instance>
        </interface>
    </hal>
    <vendor-ndk>
        <version>27</version>
    </vendor-ndk>
    <system-sdk>
        <version>27</version>
    </system-sdk>
</manifest>

Fragments de fichier manifeste

Sous Android 10 et versions ultérieures, vous pouvez associer une entrée de fichier manifeste à un module HAL dans le système de compilation. Cela permet d'inclure plus facilement le module HAL dans le système de compilation de manière conditionnelle.

Exemple

Dans votre fichier Android.bp ou Android.mk, ajoutez vintf_fragments à tout module installé explicitement sur l'appareil, comme cc_binary ou rust_binary. Par exemple, vous pouvez modifier le module avec votre implémentation de votre HAL (my.package.foo@1.0-service-bar).

... {
    ...
    vintf_fragments: ["manifest_foo.xml"],
    ...
}
LOCAL_MODULE := ...
LOCAL_VINTF_FRAGMENTS := manifest_foo.xml

Dans un fichier nommé manifest_foo.xml, créez le fichier manifeste de ce module. Au moment de la compilation, ce fichier manifeste est ajouté à l'appareil. Ajouter une entrée ici revient à ajouter une entrée dans le fichier manifeste principal de l'appareil. Cela permet aux clients d'utiliser l'interface et à VTS d'identifier les implémentations HAL présentes sur l'appareil. Ce fichier manifeste effectue tout ce qu'un fichier manifeste standard effectue.

L'exemple ci-dessous implémente android.hardware.foo@1.0::IFoo/default, qui est installé dans la partition vendor ou odm. S'il est installé sur la partition system, product ou system_ext, utilisez le type framework au lieu du type device.

<manifest version="1.0" type="device">
    <hal format="hidl">
        <name>android.hardware.foo</name>
        <transport>hwbinder</transport>
        <fqname>@1.0::IFoo/default</fqname>
    </hal>
</manifest>

Si un module HAL est empaqueté dans un APEX du fournisseur, empaquetez ses fragments VINTF associés dans le même APEX avec prebuilt_etc, comme expliqué dans la section Fragments VINTF.

Schéma du fichier manifeste

Cette section décrit la signification de ces balises XML. Certaines balises "obligatoires" peuvent être manquantes dans le fichier source de l'arborescence source Android et écrites par assemble_vintf au moment de la compilation. Les balises requises doivent être présentes dans les fichiers correspondants sur l'appareil.

?xml
Facultatif. Ne fournit des informations qu'au moteur d'analyse XML.
manifest.version
Obligatoire. Méta-version de ce fichier manifeste. Décrit les éléments attendus dans le fichier manifeste. Ne correspond pas à la version XML.
manifest.type
Obligatoire. Type de ce fichier manifeste. Il a la valeur device pour le fichier manifeste de l'appareil et framework pour le fichier manifeste du framework.
manifest.target-level
Obligatoire pour le fichier manifeste de l'appareil. Indique la version de la matrice de compatibilité du framework (FCM) avec laquelle ce fichier manifeste d'appareil doit être compatible. On parle également de version FCM de l'appareil.
manifest.hal
Facultatif, peut être répété. Un seul HAL (HIDL ou natif, tel que GL), en fonction de l'attribut format.
manifest.hal.format
Facultatif. La valeur peut être l'une des suivantes :
  • hidl: HAL HIDL Il s'agit de l'option par défaut.
  • aidl: HAL AIDL. N'est valide que pour la méta-version de fichier manifeste 2.0 ou ultérieure.
  • native: HAL natifs.
manifest.hal.max-level
Facultatif. Valide uniquement sur les fichiers manifestes de framework. Si cette valeur est définie, les HAL dont le niveau maximal est inférieur à la version FCM cible dans le fichier manifeste du framework sont désactivés.
manifest.hal.override
Facultatif. La valeur peut être l'une des suivantes :
  • true: remplace les autres éléments <hal> avec la même <name> et la même version majeure. Si aucun <version> ou <fqname> ne figure dans cet élément <hal>, l'élément <hal> déclare que ce HAL est désactivé.
  • false: ne remplacez pas les autres éléments <hal> avec la même <name> et la même version majeure.
manifest.hal.name
Obligatoire. Nom complet du package de l'HAL. Plusieurs entrées HAL peuvent utiliser le même nom. Exemples :
  • android.hardware.camera (HIDL ou AIDL HAL)
  • GLES (HAL natif, nécessite un nom uniquement)
manifest.hal.transport
Obligatoire lorsque manifest.hal.format == "hidl". Ne doit PAS être présent dans les autres cas. Indique le transport utilisé lorsqu'une interface de ce package est interrogée à partir du gestionnaire de services. La valeur peut être l'une des suivantes :
  • hwbinder: mode lié
  • passthrough: mode passthrough
Facultatif avec manifest.hal.format == "aidl". Ne doit PAS être présent dans les autres cas. Indique le mode de transport utilisé lorsqu'une interface est diffusée à distance. La valeur doit être :
  • inet: socket Inet
manifest.hal.transport.ip et manifest.hal.transport.port doivent être utilisés pour spécifier plus en détail les informations de connexion Inet.
manifest.hal.transport.arch
Obligatoire pour passthrough et ne doit pas être présent pour hwbinder. Décrit la taille d'octets du service de passthrough fourni. La valeur peut être l'une des suivantes :
  • 32: mode 32 bits
  • 64: mode 64 bits
  • 32+64: Les deux
manifest.hal.transport.ip
Obligatoire pour inet et ne doit PAS être présent dans les autres cas. Décrit l'adresse IP à partir de laquelle l'interface distante est diffusée.
manifest.hal.transport.port
Obligatoire pour inet et ne doit PAS être présent dans les autres cas. Décrit le port à partir duquel l'interface distante est diffusée.
manifest.hal.version
Facultatif, peut être répété. Version des balises hal dans un fichier manifeste.

Pour les HAL HIDL et natifs, le format est MAJOR.MINOR. Pour obtenir des exemples, consultez hardware/interfaces, vendor/${VENDOR}/interfaces, frameworks/hardware/interfaces ou system/hardware/interfaces.

Les HAL HIDL et natives peuvent utiliser plusieurs champs de version tant qu'ils représentent des versions majeures distinctes, avec une seule version mineure par version majeure fournie. Par exemple, 3.1 et 3.2 ne peuvent pas coexister, mais 1.0 et 3.4 peuvent. Cela s'applique à tous les éléments hal portant le même nom, sauf override="true". Les valeurs de <version> ne sont pas associées à <fqname>, car un <fqname> contient une version.

Pour les HAL AIDL, <version> ne doit pas être présent sur les appareils équipés d'Android 11 ou version antérieure. <version> doit être un entier unique sur les appareils équipés d'Android 12 ou version ultérieure. Il ne doit y avoir qu'un seul <version> pour chaque tuple (package, interface, instance). Si cet élément n'est pas présent, la valeur par défaut est 1. La valeur de <version> est associée à tous les <fqname> du même <hal>, car un <fqname> ne comporte pas de version.
manifest.hal.interface
Obligatoire, peut se répéter sans doublons. Indiquez une interface dans le package qui comporte un nom d'instance. Un <hal> peut contenir plusieurs éléments <interface>. Les noms doivent être distincts.
manifest.hal.interface.name
Obligatoire. Nom de l'interface.
manifest.hal.interface.instance
Obligatoire, peut être répété. Nom de l'instance de l'interface. Peut comporter plusieurs instances pour une interface, mais pas d'éléments <instance> en double.
manifest.hal.fqname
Facultatif, peut être répété. Autre méthode permettant de spécifier une instance pour le HAL avec le nom manifest.hal.name.
  • Pour les HAL HIDL, le format est @MAJOR.MINOR::INTERFACE/INSTANCE.
  • Pour les HAL AIDL, le format est INTERFACE/INSTANCE.
manifest.sepolicy
Obligatoire. Contient toutes les entrées liées à sepolicy.
manifest.sepolicy.version
Obligatoire pour le fichier manifeste de l'appareil. Déclarer la version de SELinux Il est au format SDK_INT.PLAT_INT.
manifest.vendor-ndk
Obligatoire, peut se répéter ; obligatoire pour le fichier manifeste du framework. Ne doit pas être présent dans le fichier manifeste de l'appareil. Les entrées <vendor-ndk> multiples doivent avoir des <version> différents. Décrit un ensemble d'instantanés VNDK fournis par le framework.
manifest.vendor-ndk.version
Obligatoire. Il s'agit d'un entier positif représentant la version de l'instantané VNDK.
manifest.vendor-ndk.library
Facultatif, peut se répéter, sans doublons. Décrit un ensemble de bibliothèques VNDK fournies par le framework pour cet instantané du fournisseur VNDK. La valeur correspond au nom de fichier d'une bibliothèque, par exemple libjpeg.so, y compris le préfixe lib et le suffixe .so. Aucun composant de chemin n'est autorisé.
manifest.system-sdk.version
Facultatif, peut se répéter, sans doublons ; utilisé uniquement par le fichier manifeste du framework. Décrit un ensemble de versions de SDK système fournies par le framework aux applications du fournisseur.
manifest.kernel
Facultatif. Décrit des informations statiques sur le noyau.
manifest.kernel.target-level
Facultatif. Décrit la branche du kernel. Si elle n'est pas présente, sa valeur par défaut est manifest.target-level. Doit être supérieur ou égal à manifest.target-level. Pour en savoir plus, consultez les règles de correspondance du kernel.