Manifiestos

Un objeto VINTF agrega datos de los archivos manifiesto del dispositivo y manifiesto del framework (XML). Ambos manifiestos comparten un formato, aunque no todos los elementos se aplican a ambos (para obtener detalles sobre el esquema, consulta Esquema del archivo de manifiesto).

Manifiesto del dispositivo

El manifiesto del dispositivo (proporcionado por el dispositivo) consta del manifiesto del proveedor y del manifiesto del ODM.

  • El manifiesto del proveedor especifica los HAL, las versiones de políticas de SELinux, etc., comunes a un SoC. Se recomienda colocarlo en el árbol de fuentes de Android en device/VENDOR/DEVICE/manifest.xml, pero se pueden usar varios archivos de fragmentos. Para obtener más información, consulta Fragmentos de manifiesto y Genera DM a partir de fragmentos.
  • El manifiesto de ODM enumera los HAL específicos del producto en la partición de ODM. El objeto VINTF carga el manifiesto de ODM en este orden:
    1. Si se define SKU (donde SKU es el valor de la propiedad ro.boot.product.hardware.sku), /odm/etc/vintf/manifest_SKU.xml
    2. /odm/etc/vintf/manifest.xml
    3. Si se define SKU, /odm/etc/manifest_SKU.xml
    4. /odm/etc/manifest.xml
  • El manifiesto del proveedor enumera los HAL específicos del producto en la partición del proveedor. El objeto VINTF carga el manifiesto del proveedor en este orden:
    1. Si se define SKU (donde SKU es el valor de la propiedad ro.boot.product.vendor.sku), /vendor/etc/vintf/manifest_SKU.xml
    2. /vendor/etc/vintf/manifest.xml
  • El objeto VINTF carga el manifiesto del dispositivo en este orden:
    1. Si existe el manifiesto del proveedor, combina lo siguiente:
      1. El manifiesto del proveedor
      2. Fragmentos de manifiesto de proveedor opcionales
      3. Manifiesto de ODM opcional
      4. Fragmentos de manifiesto de ODM opcionales
    2. De lo contrario, si existe el manifiesto de ODM, combínalo con los fragmentos de manifiesto de ODM opcionales.
    3. /vendor/manifest.xml (heredada, sin fragmentos)
    4. Por último, combina los fragmentos de manifiesto de cualquier APEX del proveedor. Los fragmentos de manifiesto se cargan desde el directorio etc/vintf de cada APEX (p.ej., /apex/<apex name>/etc/vintf).

    Ten en cuenta lo siguiente:

    • En los dispositivos heredados, se usan el manifiesto del proveedor heredado y el manifiesto del ODM. El manifiesto de ODM puede anular por completo el manifiesto del proveedor heredado.
    • En los dispositivos que se lanzaron con Android 9, el manifiesto de ODM se combina con el manifiesto del proveedor.
    • Cuando se combina una lista de manifiestos, los manifiestos que aparecen más adelante en la lista pueden anular las etiquetas de los manifiestos que aparecen antes en la lista, siempre que las etiquetas del manifiesto posterior tengan el atributo override="true". Por ejemplo, el manifiesto de ODM puede anular algunas etiquetas <hal> del manifiesto del proveedor. Consulta la documentación del atributo override a continuación.

Esta configuración permite que varios productos con la misma placa compartan la misma imagen del proveedor (que proporciona HAL comunes) y, sin embargo, tengan diferentes imágenes de ODM (que especifican HAL específicos del producto).

Este es un ejemplo de manifiesto de proveedor.

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

Este es un ejemplo de manifiesto de 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>

Este es un ejemplo de manifiesto de dispositivo en un paquete inalámbrico.

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

Para obtener más información, consulta Desarrollo del manifiesto del dispositivo.

Manifiesto del framework

El archivo de manifiesto del framework consta del manifiesto del sistema, el manifiesto del producto y el manifiesto system_ext.

  • El manifiesto del sistema (que proporciona Google) se genera de forma manual y se encuentra en el árbol de fuentes de Android en /system/libhidl/manifest.xml.
  • En el manifiesto del producto (que proporciona el dispositivo), se enumeran los HAL que se atienden con módulos instalados en la partición del producto.
  • El manifiesto system_ext (que proporciona el dispositivo) incluye la siguiente información:
    • HALs que se atienden con módulos instalados en la partición system_ext
    • Versiones de VNDK
    • Es la versión del SDK del sistema.

Al igual que con el manifiesto del dispositivo, se pueden usar varios archivos de fragmento. Para obtener más información, consulta Fragmentos de manifiesto.

Este es un ejemplo de manifiesto 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>

Fragmentos de manifiesto

En Android 10 y versiones posteriores, puedes asociar una entrada de manifiesto con un módulo HAL en el sistema de compilación. Esto facilita la inclusión condicional del módulo HAL en el sistema de compilación.

Ejemplo

En el archivo Android.bp o Android.mk, agrega vintf_fragments a cualquier módulo que esté instalado de forma explícita en el dispositivo, como cc_binary o rust_binary. Por ejemplo, puedes modificar el módulo con tu implementación de HAL (my.package.foo@1.0-service-bar).

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

En un archivo llamado manifest_foo.xml, crea el manifiesto para este módulo. En el momento de la compilación, este manifiesto se agrega al dispositivo. Agregar una entrada aquí es lo mismo que agregar una entrada en el manifiesto principal del dispositivo. Esto permite que los clientes usen la interfaz y que VTS identifique qué implementaciones de HAL están en el dispositivo. Este manifiesto también hace todo lo que hace un manifiesto normal.

En el siguiente ejemplo, se implementa android.hardware.foo@1.0::IFoo/default, que se instala en la partición vendor o odm. Si está instalado en la partición system, product o system_ext, usa el tipo framework en lugar del 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>

Si un módulo HAL se empaqueta en un APEX del proveedor, empaqueta sus fragmentos de VINTF asociados dentro del mismo APEX con prebuilt_etc, como se explica en Fragmentos de VINTF.

Esquema del archivo de manifiesto

En esta sección, se describe el significado de estas etiquetas XML. Es posible que falten algunas etiquetas "obligatorias" en el archivo fuente del árbol de fuentes de Android y que assemble_vintf las escriba en el momento de la compilación. Las etiquetas obligatorias deben estar presentes en los archivos correspondientes del dispositivo.

?xml
Opcional. Solo proporciona información al analizador de XML.
manifest.version
Obligatorio. Es la metaversión de este manifiesto. Describe los elementos que se esperan en el manifiesto. No se relaciona con la versión de XML.
manifest.type
Obligatorio. Es el tipo de este manifiesto. Tiene el valor device para el archivo de manifiesto del dispositivo y framework para el archivo de manifiesto del framework.
manifest.target-level
Es obligatorio para el manifiesto del dispositivo. Especifica la versión de la matriz de compatibilidad del framework (FCM) con la que este manifiesto del dispositivo debe ser compatible. También se denomina la versión de FCM de envío del dispositivo.
manifest.hal
Opcional, se puede repetir. Un solo HAL (HIDL o nativo, como GL), según el atributo format.
manifest.hal.format
Opcional. El valor puede ser uno de los siguientes:
  • hidl: HAL de HIDL Es el valor predeterminado.
  • aidl: HAL de AIDL Solo es válido en la metaversión del manifiesto 2.0 y versiones posteriores.
  • native: HALs nativos.
manifest.hal.max-level
Opcional. Solo es válido en manifiestos de framework. Si se establece, se inhabilitan los HAL con un nivel máximo inferior a la versión de FCM objetivo en el manifiesto del framework.
manifest.hal.override
Opcional. El valor puede ser uno de los siguientes:
  • true: Anula otros elementos <hal> con la misma <name> y la misma versión principal. Si no hay <version> ni <fqname> en este elemento <hal>, el elemento <hal> declara que este HAL se inhabilita.
  • false: No anules otros elementos <hal> con la misma <name> y versión principal.
manifest.hal.name
Obligatorio. Es el nombre de paquete completamente calificado del sistema HAL. Varias entradas de HAL pueden usar el mismo nombre. Ejemplos:
  • android.hardware.camera (HAL de HIDL o AIDL)
  • GLES (HAL nativo, solo requiere el nombre)
manifest.hal.transport
Obligatorio cuando manifest.hal.format == "hidl". De lo contrario, NO debe estar presente. Indica qué transporte se usa cuando se consulta una interfaz de este paquete desde el administrador de servicios. El valor puede ser uno de los siguientes:
  • hwbinder: Modo vinculado
  • passthrough: Modo de transferencia
Opcional cuando es manifest.hal.format == "aidl". De lo contrario, NO debe estar presente. Indica qué transporte se usa cuando se entrega una interfaz de forma remota. El valor debe ser:
  • inet: Socket de Inet
Se deben usar manifest.hal.transport.ip y manifest.hal.transport.port para especificar mejor la información de la conexión de Inet.
manifest.hal.transport.arch
Obligatorio para passthrough y no debe estar presente para hwbinder. Describe la cantidad de bits del servicio de transferencia que se proporciona. El valor puede ser uno de los siguientes:
  • 32: Modo de 32 bits
  • 64: Modo de 64 bits
  • 32+64: Ambas
manifest.hal.transport.ip
Es obligatorio para inet y NO debe estar presente de otra manera. Describe la dirección IP desde la que se entrega la interfaz remota.
manifest.hal.transport.port
Es obligatorio para inet y NO debe estar presente de otra manera. Describe el puerto desde el que se entrega la interfaz remota.
manifest.hal.version
Opcional, se puede repetir. Es una versión para las etiquetas hal en un manifiesto.

Para HIDL y HAL nativos, el formato es MAJOR.MINOR. Para ver ejemplos, consulta hardware/interfaces, vendor/${VENDOR}/interfaces, frameworks/hardware/interfaces o system/hardware/interfaces.

HIDL y los HAL nativos pueden usar varios campos de versión, siempre que representen versiones principales distintas, con solo una versión secundaria por versión principal proporcionada. Por ejemplo, 3.1 y 3.2 no pueden coexistir, pero 1.0 y 3.4 sí. Esto se aplica a todos los elementos hal con el mismo nombre, a menos que sea override="true". Los valores de <version> no se asocian con <fqname> porque un <fqname> lleva una versión.

En el caso de los HAL de AIDL, <version> no debe estar presente en dispositivos que ejecutan Android 11 y versiones anteriores. <version> debe ser un número entero único en dispositivos que ejecutan Android 12 y versiones posteriores. Debe haber un máximo de un <version> para cada tupla (package, interface, instance). Si no está presente, el valor predeterminado es 1. El valor de <version> está asociado con todos los <fqname> en el mismo <hal> porque un <fqname> no lleva una versión.
manifest.hal.interface
Obligatorio, se puede repetir sin duplicados. Indica una interfaz en el paquete que tenga un nombre de instancia. Pueden haber varios elementos <interface> en un <hal>; los nombres deben ser distintos.
manifest.hal.interface.name
Obligatorio. Es el nombre de la interfaz.
manifest.hal.interface.instance
Obligatorio, se puede repetir. Es el nombre de la instancia de la interfaz. Puede tener varias instancias para una interfaz, pero no elementos <instance> duplicados.
manifest.hal.fqname
Opcional, se puede repetir. Es una forma alternativa de especificar una instancia para el HAL con el nombre manifest.hal.name.
  • Para los HAL de HIDL, el formato es @MAJOR.MINOR::INTERFACE/INSTANCE.
  • Para los HAL de AIDL, el formato es INTERFACE/INSTANCE.
manifest.sepolicy
Obligatorio. Contiene todas las entradas relacionadas con sepolicy.
manifest.sepolicy.version
Es obligatorio para el manifiesto del dispositivo. Declara la versión de SELinux. Tiene el formato SDK_INT.PLAT_INT.
manifest.vendor-ndk
Obligatorio, se puede repetir; obligatorio para el manifiesto del framework. No debe estar presente en el manifiesto del dispositivo. Las entradas <vendor-ndk> múltiples deben tener <version> diferentes. Describe un conjunto de instantáneas del VNDK que proporciona el framework.
manifest.vendor-ndk.version
Obligatorio. Es un número entero positivo que representa la versión de la instantánea del VNDK.
manifest.vendor-ndk.library
Opcional, se puede repetir sin duplicados. Describe un conjunto de bibliotecas del VNDK que proporciona el framework para este resumen del proveedor del VNDK. El valor es el nombre de archivo de una biblioteca, p.ej., libjpeg.so, incluido el prefijo lib y el sufijo .so. No se permiten componentes de ruta.
manifest.system-sdk.version
Opcional, se puede repetir sin duplicados; solo lo usa el manifiesto del framework. Describe un conjunto de versiones del SDK del sistema que proporciona el framework a las apps del proveedor.
manifest.kernel
Opcional. Describe información estática sobre el kernel.
manifest.kernel.target-level
Opcional. Describe la rama del kernel. Su valor predeterminado es manifest.target-level si no está presente. Debe ser mayor o igual que manifest.target-level. Consulta las reglas de coincidencia del kernel para obtener más información.