Manifest

Un oggetto VINTF aggrega i dati dei file manifest del dispositivo e manifest del framework (XML). Entrambi i manifest condividono un formato, anche se non tutti gli elementi si applicano a entrambi (per informazioni dettagliate sullo schema, consulta Schema file manifest).

File manifest del dispositivo

Il manifest del dispositivo (fornito dal dispositivo) è costituito dal manifest del fornitore e dal manifest ODM.

  • Il manifest del fornitore specifica HAL, versioni dei criteri SELinux e così via comuni a un SoC. È consigliabile posizionarlo nella struttura ad albero delle sorgenti di Android in device/VENDOR/DEVICE/manifest.xml, ma è possibile utilizzare più file di frammenti. Per maggiori dettagli, vedi Fragmenti manifest e Generare DM dai frammenti.
  • Il manifest ODM elenca gli HAL specifici del prodotto nella partizione ODM. L'oggetto VINTF carica il manifest ODM in questo ordine:
    1. Se SKU è definito (dove SKU è il valore della proprietà ro.boot.product.hardware.sku), /odm/etc/vintf/manifest_SKU.xml
    2. /odm/etc/vintf/manifest.xml
    3. Se SKU è definito, /odm/etc/manifest_SKU.xml
    4. /odm/etc/manifest.xml
  • Il manifest del fornitore elenca gli HAL specifici del prodotto nella partizione del fornitore. L'oggetto VINTF carica il manifest del fornitore in questo ordine:
    1. Se SKU è definito (dove SKU è il valore della proprietà ro.boot.product.vendor.sku), /vendor/etc/vintf/manifest_SKU.xml
    2. /vendor/etc/vintf/manifest.xml
  • L'oggetto VINTF carica il manifest del dispositivo in questo ordine:
    1. Se il manifest del fornitore esiste, combina quanto segue:
      1. Il manifest del fornitore
      2. Frammenti manifest del fornitore facoltativi
      3. Manifest ODM facoltativo
      4. Frammenti manifest ODM facoltativi
    2. In caso contrario, se il manifest ODM esiste, combinalo con i frammenti facoltativi del manifest ODM.
    3. /vendor/manifest.xml (legacy, senza frammenti)
    4. Infine, combina i frammenti manifest di qualsiasi APEX del fornitore. I frammenti manifest vengono caricati dalla directory etc/vintf di ogni APEX (ad es. /apex/<apex name>/etc/vintf).

    Tieni presente che:

    • Sui dispositivi legacy vengono utilizzati il manifest del fornitore legacy e il manifest ODM. Il file manifest ODM potrebbe sostituire completamente il file manifest del fornitore precedente.
    • Sui dispositivi lanciati con Android 9, il manifest ODM viene combinato con il manifest del fornitore.
    • Quando combini un elenco di manifest, i manifest che compaiono più avanti nell'elenco possono sostituire i tag dei manifest che compaiono più avanti nell'elenco, a condizione che i tag nel manifest successivo abbiano l'attributo override="true". Ad esempio, il manifest ODM potrebbe override alcuni tag <hal> del manifest del fornitore. Consulta la documentazione relativa all'attributo override di seguito.

Questa configurazione consente a più prodotti con la stessa scheda di condividere la stessa immagine del fornitore (che fornisce HAL comuni) e di avere immagini ODM diverse (che specificano HAL specifici per il prodotto).

Ecco un esempio di manifest del fornitore.

<?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>

Ecco un esempio di manifest 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>

Ecco un esempio di manifest del dispositivo in un pacchetto 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>

Per maggiori dettagli, consulta Sviluppo di manifest del dispositivo.

File manifest del framework

Il file manifest del framework è costituito dal manifest di sistema, dal manifest del prodotto e dal manifest system_ext.

  • Il file manifest di sistema (fornito da Google) viene generato manualmente e si trova nella struttura di origine di Android in /system/libhidl/manifest.xml.
  • Il manifest del prodotto (fornito dal dispositivo) elenca gli HAL gestiti dai moduli installati nella partizione del prodotto.
  • Il file manifest system_ext (fornito dal dispositivo) elenca quanto segue:
    • HAL gestiti da moduli installati nella partizione system_ext;
    • Versioni VNDK.
    • Versione dell'SDK di sistema.

Come per il manifest del dispositivo, è possibile utilizzare più file di frammenti. Per maggiori dettagli, consulta Fragmenti manifest.

Ecco un esempio di manifest del 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>

Frammenti manifest

In Android 10 e versioni successive, puoi associare una voce del manifest a un modulo HAL nel sistema di compilazione. In questo modo è più facile includere condizionatamente il modulo HAL nel sistema di compilazione.

Esempio

Nel file Android.bp o Android.mk, aggiungi vintf_fragments a qualsiasi modulo installato esplicitamente sul dispositivo, ad esempio cc_binary o rust_binary. Ad esempio, puoi modificare il modulo con la tua implementazione dell'HAL (my.package.foo@1.0-service-bar).

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

In un file denominato manifest_foo.xml, crea il manifest per questo modulo. Al momento della compilazione, questo manifest viene aggiunto al dispositivo. L'aggiunta di una voce qui equivale all'aggiunta di una voce nel file manifest principale del dispositivo. In questo modo i client possono utilizzare l'interfaccia e VTS può identificare le implementazioni HAL sul dispositivo. Questo manifest può fare tutto ciò che fa un manifest normale.

L'esempio riportato di seguito implementa android.hardware.foo@1.0::IFoo/default, che viene installato nella partizione vendor o odm. Se è installato nella partizione system, product o system_ext, utilizza il tipo framework anziché il tipo 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>

Se un modulo HAL è pacchettizzato in un APEX del fornitore, pacchettizza i relativi frammenti VINTF nello stesso APEX con prebuilt_etc come spiegato in Frammenti VINTF.

Schema del file manifest

Questa sezione descrive il significato di questi tag XML. Alcuni tag "obbligatori" possono essere mancanti nel file di origine nella struttura di origine di Android e scritti da assemble_vintf al momento della compilazione. I tag obbligatori devono essere presenti nei file corrispondenti sul dispositivo.

?xml
Facoltativo. Fornisce informazioni solo al parser XML.
manifest.version
Obbligatorio. Meta-versione di questo manifest. Descrive gli elementi previsti nel file manifest. Non correlato alla versione XML.
manifest.type
Obbligatorio. Tipo di manifest. Ha il valore device per il file manifest del dispositivo e framework per il file manifest del framework.
manifest.target-level
Obbligatorio per il manifest del dispositivo. Specifica la versione della matrice di compatibilità del framework (FCM) con cui deve essere compatibile questo manifest del dispositivo. Questa è anche chiamata versione FCM preinstallata del dispositivo.
manifest.hal
Facoltativo, può essere ripetuto. Un singolo HAL (HIDL o nativo, ad esempio GL), a seconda dell'attributo format.
manifest.hal.format
Facoltativo. Il valore può essere uno dei seguenti:
  • hidl: HAL HIDL. Questa è l'impostazione predefinita.
  • aidl: HAL AIDL. Valido solo per la meta-versione del manifest 2.0 e successive.
  • native: HAL nativi.
manifest.hal.max-level
Facoltativo. Valido solo per i manifest del framework. Se impostato, gli HAL con un livello massimo inferiore alla versione FCM target nel manifest del framework vengono disattivati.
manifest.hal.override
Facoltativo. Il valore può essere uno dei seguenti:
  • true: sostituisci gli altri elementi <hal> con lo stesso <name> e la stessa versione principale. Se non sono presenti elementi <version> o <fqname> in questo elemento <hal>, l'elemento <hal> dichiara che questo HAL è disattivato.
  • false: non eseguire l'override di altri elementi <hal> con la stessa versione principale e <name>.
manifest.hal.name
Obbligatorio. Nome completo del pacchetto dell'HAL. Più voci HAL possono utilizzare lo stesso nome. Esempi:
  • android.hardware.camera (HAL HIDL o AIDL)
  • GLES (HAL nativo, richiede solo il nome)
manifest.hal.transport
Obbligatorio quando manifest.hal.format == "hidl". NON deve essere presente altrimenti. Indica il trasporto utilizzato quando viene eseguita una query su un'interfaccia di questo pacchetto dal gestore del servizio. Il valore può essere uno dei seguenti:
  • hwbinder: modalità con pacchetti
  • passthrough: modalità passthrough
Facoltativo quando manifest.hal.format == "aidl". NON deve essere presente altrimenti. Indica il trasporto utilizzato quando un'interfaccia viene pubblicata remotely. Il valore deve essere:
  • inet: presa Inet
manifest.hal.transport.ip e manifest.hal.transport.port devono essere utilizzati per specificare ulteriormente le informazioni di connessione Inet.
manifest.hal.transport.arch
Obbligatorio per passthrough e non deve essere presente per hwbinder. Descrive la dimensione in bit del servizio passthrough fornito. Il valore può essere uno dei seguenti:
  • 32: modalità a 32 bit
  • 64: modalità a 64 bit
  • 32+64: Entrambi
manifest.hal.transport.ip
Obbligatorio per inet e NON deve essere presente in caso contrario. Descrive l'indirizzo IP da cui viene pubblicata l'interfaccia remota.
manifest.hal.transport.port
Obbligatorio per inet e NON deve essere presente in caso contrario. Descrive la porta da cui viene pubblicata l'interfaccia remota.
manifest.hal.version
Facoltativo, può essere ripetuto. Una versione per i tag hal in un manifest.

Per HIDL e HAL nativi, il formato è MAJOR.MINOR. Per esempi, consulta hardware/interfaces,vendor/${VENDOR}/interfaces,frameworks/hardware/interfaces osystem/hardware/interfaces.

Gli HAL HIDL e nativi possono utilizzare più campi di versione purché rappresentino versioni principali distinte, con una sola versione minore per ogni versione principale. Ad esempio, 3.1 e 3.2 non possono coesistere, ma 1.0 e 3.4 possono. Questo vale per tutti gli elementi hal con lo stesso nome, a meno che override="true". I valori di <version> non sono associati a <fqname> perché un <fqname> contiene una versione.

Per gli HAL AIDL, <version> non deve essere presente sui dispositivi con Android 11 o versioni precedenti. <version> deve essere un singolo numero intero sui dispositivi con Android 12 e versioni successive. Deve esserci al massimo un <version> per ogni (package, interface, instance) tupla. Se non è presente, il valore predefinito è 1. Il valore di <version> è associato a tutti i <fqname> nello stesso <hal> perché un <fqname> non ha una versione.
manifest.hal.interface
Obbligatorio, può essere ripetuto senza duplicati. Indica un'interfaccia nel pacchetto che abbia un nome di istanza. In un <hal> possono essere presenti più elementi <interface>; i nomi devono essere distinti.
manifest.hal.interface.name
Obbligatorio. Nome dell'interfaccia.
manifest.hal.interface.instance
Obbligatorio, può essere ripetuto. Nome istanza dell'interfaccia. Può avere più istanze per un'interfaccia, ma nessun elemento <instance> duplicato.
manifest.hal.fqname
Facoltativo, può essere ripetuto. Un modo alternativo per specificare un'istanza per l'HAL con nome manifest.hal.name.
  • Per le HAL HIDL, il formato è @MAJOR.MINOR::INTERFACE/INSTANCE.
  • Per gli HAL AIDL, il formato è INTERFACE/INSTANCE.
manifest.sepolicy
Obbligatorio. Contiene tutte le voci relative a sepolicy.
manifest.sepolicy.version
Obbligatorio per il manifest del dispositivo. Dichiara la versione di SELinux. Ha il formato SDK_INT.PLAT_INT.
manifest.vendor-ndk
Obbligatorio, può essere ripetuto; obbligatorio per il manifest del framework. Non deve essere presente nel file manifest del dispositivo. Più voci <vendor-ndk> devono avere <version> diversi. Descrive un insieme di snapshot VNDK fornito dal framework.
manifest.vendor-ndk.version
Obbligatorio. Si tratta di un numero intero positivo che rappresenta la versione dello snapshot VNDK.
manifest.vendor-ndk.library
Facoltativo, può essere ripetuto senza duplicati. Descrive un insieme di librerie VNDK fornito dal framework per questo snapshot del fornitore VNDK. Il valore è il nome file di una libreria, ad esempio libjpeg.so, incluso il prefisso lib e il suffisso .so. Non sono consentiti componenti del percorso.
manifest.system-sdk.version
Facoltativo, può essere ripetuto senza duplicati; utilizzato solo dal manifest del framework. Descrive un insieme di versioni dell'SDK di sistema fornite dal framework alle app del fornitore.
manifest.kernel
Facoltativo. Descrive informazioni statiche sul kernel.
manifest.kernel.target-level
Facoltativo. Descrive il ramo del kernel. Se non è presente, il valore predefinito è manifest.target-level. Deve essere maggiore o uguale a manifest.target-level. Per maggiori dettagli, consulta le regole di corrispondenza del kernel.