Manifestos

Um objeto VINTF agrega dados de arquivos de manifesto do dispositivo e de manifesto do framework (XML). Os dois manifestos compartilham um formato, embora nem todos os elementos se apliquem a ambos. Para detalhes sobre o esquema, consulte Esquema de arquivo de manifesto.

Manifesto do dispositivo

O manifesto do dispositivo (fornecido pelo dispositivo) consiste no manifesto do fornecedor e no manifesto do ODM.

  • O manifesto do fornecedor especifica HALs, versões de política do SELinux etc. comuns a um SoC. Ele é recomendado para ser colocado na árvore de origem do Android em device/VENDOR/DEVICE/manifest.xml, mas vários arquivos de fragmento podem ser usados. Para mais detalhes, consulte Fragmentos de manifesto e Gerar DM de fragmentos.
  • O manifesto do ODM lista HALs específicos para o produto na partição do ODM. O objeto VINTF carrega o manifesto ODM nesta ordem:
    1. Se SKU for definido (em que SKU é o valor da propriedade ro.boot.product.hardware.sku), /odm/etc/vintf/manifest_SKU.xml
    2. /odm/etc/vintf/manifest.xml
    3. Se SKU for definido, /odm/etc/manifest_SKU.xml
    4. /odm/etc/manifest.xml
  • O manifesto do fornecedor lista HALs específicos para o produto na partição do fornecedor. O objeto VINTF carrega o manifesto do fornecedor nesta ordem:
    1. Se SKU for definido (em que SKU é o valor da propriedade ro.boot.product.vendor.sku), /vendor/etc/vintf/manifest_SKU.xml
    2. /vendor/etc/vintf/manifest.xml
  • O objeto VINTF carrega o manifesto do dispositivo nesta ordem:
    1. Se o manifesto do fornecedor existir, combine o seguinte:
      1. O manifesto do fornecedor
      2. Fragmentos de manifesto do fornecedor opcionais
      3. Manifesto ODM opcional
      4. Fragmentos de manifesto ODM opcionais
    2. Caso contrário, se o manifesto ODM existir, combine-o com os fragmentos de manifesto ODM opcionais.
    3. /vendor/manifest.xml (legado, sem fragmentos)
    4. Por fim, combine fragmentos de manifesto de qualquer APEX de fornecedor. Os fragmentos de manifesto são carregados do diretório etc/vintf de cada APEX (por exemplo, /apex/<apex name>/etc/vintf).

    Algumas considerações:

    • Em dispositivos legados, o manifesto do fornecedor legado e o manifesto do ODM são usados. O manifesto ODM pode substituir completamente o manifesto do fornecedor legado.
    • Em dispositivos lançados com o Android 9, o manifesto ODM é combinado com o manifesto do fornecedor.
    • Ao combinar uma lista de manifestos, os manifestos que aparecem mais tarde na lista podem substituir as tags que aparecem mais cedo na lista, desde que as tags no manifesto mais recente tenham o atributo override="true". Por exemplo, o manifesto ODM pode substituir algumas tags <hal> do manifesto do fornecedor. Consulte a documentação do atributo override abaixo.

Essa configuração permite que vários produtos com a mesma placa compartilhem a mesma imagem do fornecedor (que fornece HALs comuns), mas tenham imagens ODM diferentes (que especificam HALs específicos do produto).

Confira um exemplo de manifesto do fornecedor.

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

Confira um exemplo de manifesto 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>

Confira um exemplo de manifesto do dispositivo em um pacote 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>

Para mais detalhes, consulte Desenvolvimento de manifestos de dispositivos.

Manifesto do framework

O arquivo de manifesto do framework consiste no manifesto do sistema, no manifesto do produto e no manifesto system_ext.

  • O manifesto do sistema (fornecido pelo Google) é gerado manualmente e fica na árvore de origem do Android em /system/libhidl/manifest.xml.
  • O manifesto do produto (fornecido pelo dispositivo) lista os HALs atendidos por módulos instalados na partição do produto.
  • O manifesto system_ext (fornecido pelo dispositivo) lista o seguinte:
    • HALs atendidos por módulos instalados na partição system_ext;
    • Versões do VNDK;
    • Versão do SDK do sistema.

Assim como no manifesto do dispositivo, vários arquivos de fragmento podem ser usados. Para mais detalhes, consulte Fragmentos de manifesto.

Confira um exemplo de manifesto 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 manifesto

No Android 10 e versões mais recentes, é possível associar uma entrada de manifesto a um módulo HAL no sistema de build. Isso facilita a inclusão condicional do módulo HAL no sistema de build.

Exemplo

No arquivo Android.bp ou Android.mk, adicione vintf_fragments a qualquer módulo instalado explicitamente no dispositivo, como cc_binary ou rust_binary. Por exemplo, é possível modificar o módulo com a implementação do HAL (my.package.foo@1.0-service-bar).

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

Em um arquivo chamado manifest_foo.xml, crie o manifesto para esse módulo. No momento do build, esse manifesto é adicionado ao dispositivo. Adicionar uma entrada aqui é o mesmo que adicionar uma entrada no manifesto principal do dispositivo. Isso permite que os clientes usem a interface e permite que o VTS identifique quais implementações do HAL estão no dispositivo. Tudo o que um manifesto normal faz, esse manifesto também faz.

O exemplo abaixo implementa android.hardware.foo@1.0::IFoo/default, que é instalado na partição vendor ou odm. Se ele estiver instalado na partição system, product ou system_ext, use o tipo framework em vez do 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 um módulo HAL for empacotado em um APEX do fornecedor, empacote os fragmentos VINTF associados no mesmo APEX com prebuilt_etc, conforme explicado em Fragmentos VINTF.

Esquema do arquivo de manifesto

Esta seção descreve o significado dessas tags XML. Algumas tags "required" podem estar ausentes do arquivo de origem na árvore de origem do Android e serem gravadas por assemble_vintf no momento da build. As tags obrigatórias precisam estar presentes nos arquivos correspondentes no dispositivo.

?xml
Opcional. Só fornece informações para o analisador XML.
manifest.version
Obrigatório. Metaversão do manifesto. Descreve os elementos esperados no manifesto. Não está relacionado à versão do XML.
manifest.type
Obrigatório. Tipo do manifesto. Ele tem o valor device para o arquivo de manifesto do dispositivo e framework para o arquivo de manifesto da framework.
manifest.target-level
Obrigatório para o manifesto do dispositivo. Especifica a versão da matriz de compatibilidade do framework (FCM, na sigla em inglês) com que o manifesto do dispositivo precisa ser compatível. Isso também é chamado de versão do FCM do dispositivo.
manifest.hal
Opcional, pode repetir. Um único HAL (HIDL ou nativo, como GL), dependendo do atributo format.
manifest.hal.format
Opcional. O valor pode ser um destes:
  • hidl: HALs do HIDL. Esse é o padrão.
  • aidl: HALs AIDL. Válido apenas na metaversão 2.0 do manifesto e em versões mais recentes.
  • native: HALs nativos.
manifest.hal.max-level
Opcional. Válido apenas em manifestos de framework. Se definido, as HALs com um nível máximo menor do que a versão do FCM de destino no manifesto do framework serão desativadas.
manifest.hal.override
Opcional. O valor pode ser um destes:
  • true: substitui outros elementos <hal> com a mesma <name> e versão principal. Se nenhum <version> ou <fqname> estiver neste elemento <hal>, o elemento <hal> vai declarar que esse HAL está desativado.
  • false: não substitua outros elementos <hal> com a mesma <name> e versão principal.
manifest.hal.name
Obrigatório. Nome do pacote totalmente qualificado do HAL. Várias entradas HAL podem usar o mesmo nome. Exemplos:
  • android.hardware.camera (HAL de HIDL ou AIDL)
  • GLES (HAL nativo, requer apenas o nome)
manifest.hal.transport
Obrigatório quando manifest.hal.format == "hidl". Caso contrário, não precisa estar presente. Informa qual transporte é usado quando uma interface desse pacote é consultada pelo gerenciador de serviços. O valor pode ser um destes:
  • hwbinder: modo de vinculação
  • passthrough: modo de passagem
Opcional quando manifest.hal.format == "aidl". Caso contrário, não precisa estar presente. Indica qual transporte é usado quando uma interface é transmitida remotamente. O valor precisa ser:
  • inet: socket Inet
Os elementos manifest.hal.transport.ip e manifest.hal.transport.port precisam ser usados para especificar melhor as informações de conexão da Inet.
manifest.hal.transport.arch
Obrigatório para passthrough e não pode estar presente para hwbinder. Descreve o tamanho do serviço de passagem fornecido. O valor pode ser um destes:
  • 32: modo de 32 bits
  • 64: modo de 64 bits
  • 32+64: ambas
manifest.hal.transport.ip
Obrigatório para inet e NÃO pode estar presente. Descreve o endereço IP em que a interface remota está sendo veiculada.
manifest.hal.transport.port
Obrigatório para inet e NÃO pode estar presente. Descreve a porta em que a interface remota está sendo servida.
manifest.hal.version
Opcional, pode repetir. Uma versão para as tags hal em um manifesto.

Para HIDL e HALs nativos, o formato é MAJOR.MINOR. Para exemplos, consulte hardware/interfaces, vendor/${VENDOR}/interfaces, frameworks/hardware/interfaces ou system/hardware/interfaces.

O HIDL e os HALs nativos podem usar vários campos de versão, desde que representem versões principais distintas, com apenas uma versão secundária por versão principal fornecida. Por exemplo, 3.1 e 3.2 não podem coexistir, mas 1.0 e 3.4 podem. Isso se aplica a todos os elementos hal com o mesmo nome, a menos que override="true". Os valores de <version> não são associados a <fqname> porque um <fqname> carrega uma versão.

Para HALs AIDL, <version> não pode estar presente em dispositivos com Android 11 e versões anteriores. <version> precisa ser um número inteiro único em dispositivos com o Android 12 e versões mais recentes. É preciso ter no máximo um <version> para cada tupla (package, interface, instance). Se não estiver presente, o padrão será 1. O valor de <version> é associado a todos os <fqname> no mesmo <hal> porque um <fqname> não tem uma versão.
manifest.hal.interface
Obrigatório, pode ser repetido sem duplicações. Declare uma interface no pacote que tenha um nome de instância. Pode haver vários elementos <interface> em uma <hal>. Os nomes precisam ser distintos.
manifest.hal.interface.name
Obrigatório. Nome da interface.
manifest.hal.interface.instance
Obrigatório, pode ser repetido. Nome da instância da interface. Pode ter várias instâncias para uma interface, mas nenhum elemento <instance> duplicado.
manifest.hal.fqname
Opcional, pode repetir. Uma maneira alternativa de especificar uma instância para o HAL com o nome manifest.hal.name.
  • Para HALs HIDL, o formato é @MAJOR.MINOR::INTERFACE/INSTANCE.
  • Para HALs da AIDL, o formato é INTERFACE/INSTANCE.
manifest.sepolicy
Obrigatório. Contém todas as entradas relacionadas à política de segurança.
manifest.sepolicy.version
Obrigatório para o manifesto do dispositivo. Declara a versão do SELinux. Ele tem o formato SDK_INT.PLAT_INT.
manifest.vendor-ndk
Obrigatório, pode ser repetido; obrigatório para o manifesto do framework. Não pode estar presente no manifesto do dispositivo. Várias entradas de <vendor-ndk> precisam ter <version>s diferentes. Descreve um conjunto de snapshots do VNDK fornecidos pelo framework.
manifest.vendor-ndk.version
Obrigatório. É um número inteiro positivo que representa a versão do snapshot do VNDK.
manifest.vendor-ndk.library
Opcional, pode ser repetido, sem duplicações. Descreve um conjunto de bibliotecas do VNDK fornecido pelo framework para este snapshot do fornecedor do VNDK. O valor é o nome de arquivo de uma biblioteca, por exemplo, libjpeg.so, incluindo o prefixo lib e o sufixo .so. Nenhum componente de caminho é permitido.
manifest.system-sdk.version
Opcional, pode ser repetido, sem duplicações; usado apenas pelo manifesto do framework. Descreve um conjunto de versões do SDK do sistema fornecidas pelo framework para apps do fornecedor.
manifest.kernel
Opcional. Descreve informações estáticas sobre o kernel.
manifest.kernel.target-level
Opcional. Descreve a ramificação do kernel. O valor padrão é manifest.target-level se não estiver presente. Precisa ser maior que ou igual a manifest.target-level. Consulte as regras de correspondência do kernel para mais detalhes.